• 图论09-桥和割点


    1 寻找桥的算法

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    2 桥的代码实现

    package Chapt06_Bridge;
    
    import java.util.ArrayList;
    
    public class FindBridges {
    
        private Graph G;
        private boolean[] visited;
    
        //ord数组记录访问的顺序
        private int ord[];
    
        //low数组记录该顶点可以访问到的ord[值]最小的[顶点]
        private int low[];
    
        //cnt用来记录步数,给order赋值
        private int cnt;
    
        // Edge类型的动态数组
        private ArrayList<Edge> res;
    
        public FindBridges(Graph G){
            this.G = G;
            visited = new boolean[G.V()];
            res = new ArrayList<>();
            ord = new int[G.V()];
            low = new int[G.V()];
            cnt = 0;
    
            for(int v = 0; v < G.V(); v ++)
                if(!visited[v])
                    dfs(v, v);
        }
    
        private void dfs(int v, int parent){
    
            visited[v] = true;
            ord[v] = cnt;
    
            // 初始的时候,low的值就是访问的顺序值,在递归return的时候才进行更新
            low[v] = ord[v];
    
            cnt ++;
    
            // 通过邻接表,挨个查找相邻的节点
            for(int w: G.adj(v))
                //如果有相邻的节点还没有被访问过,就dfs
                if(!visited[w]){
                    dfs(w, v);
    
                    // 对上一个节点的low值进行更新
                    low[v] = Math.min(low[v], low[w]);
    
                    // 如果子节点的low值比父节点的ord大,说明两点之间是一座桥。
                    // 因为如果都在同一个环内,low值一定是父节点之前的节点,数字会更小,那么就不是桥,桥是不可回头的。
                    if(low[w] > ord[v])
                        res.add(new Edge(v, w));
                }
                else if(w != parent) //如果该点访问过,不继续dfs,只更新low值
                    low[v] = Math.min(low[v], low[w]);
        }
    
        public ArrayList<Edge> result(){
            return res;
        }
    
        public static void main(String[] args){
    
            Graph g = new Graph("g2.txt");
            FindBridges fb = new FindBridges(g);
            System.out.println("Bridges in g2 : " + fb.result());
    
            Graph g2 = new Graph("g8.txt");
            FindBridges fb2 = new FindBridges(g2);
            System.out.println("Bridges in g8 : " + fb2.result());
    
            Graph g3 = new Graph("g3.txt");
            FindBridges fb3 = new FindBridges(g3);
            System.out.println("Bridges in g3 : " + fb3.result());
    
            Graph tree = new Graph("tree.txt");
            FindBridges fb_tree = new FindBridges(tree);
            System.out.println("Bridges in tree : " + fb_tree.result());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    在这里插入图片描述

    3 寻找割点的算法

    在这里插入图片描述
    在这里插入图片描述

    4 割点的代码实现

    package Chapt06_Bridge_And_CutPoints;
    
    import java.util.HashSet;
    
    public class FindCutPoints {
    
        private Graph G;
        private boolean[] visited;
    
        private int[] ord;
        private int[] low;
        private int cnt;
    
        private HashSet<Integer> res;
    
        public FindCutPoints(Graph G){
    
            this.G = G;
            visited = new boolean[G.V()];
    
            res = new HashSet<>();
            ord = new int[G.V()];
            low = new int[G.V()];
            cnt = 0;
    
            for(int v = 0; v < G.V(); v ++)
                if(!visited[v])
                    dfs(v, v);
        }
    
        private void dfs(int v, int parent){
    
            visited[v] = true;
            ord[v] = cnt;
            low[v] = ord[v];
            cnt ++;
    
            // 记录子节点的数量
            int child = 0;
    
            for(int w: G.adj(v))
                if(!visited[w]){
                    dfs(w, v);
                    low[v] = Math.min(low[v], low[w]);
    
                    //割点的判断
                    if(v != parent && low[w] >= ord[v])
                        res.add(v);
    
                    child ++;
                    if(v == parent && child > 1)
                        res.add(v);
    
                   // if(v == parent && child = 1) -- 单环肯定不是割点
                }
                else if(w != parent)
                    low[v] = Math.min(low[v], low[w]);
        }
    
        public HashSet<Integer> result(){
            return res;
        }
    
        public static void main(String[] args){
    
            Graph g = new Graph("g8.txt");
            FindCutPoints fc = new FindCutPoints(g);
            System.out.println("Cut Points in g8 : " + fc.result());
    
            Graph g2 = new Graph("g2.txt");
            FindCutPoints fc2 = new FindCutPoints(g2);
            System.out.println("Cut Points in g2 : " + fc2.result());
    
            Graph tree = new Graph("tree.txt");
            FindCutPoints fc3 = new FindCutPoints(tree);
            System.out.println("Cut Points in tree : " + fc3.result());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    在这里插入图片描述

  • 相关阅读:
    卷积神经网络基础概念理解(二)
    重入漏洞Victim
    《第一堂棒球课》:王牌左外野·棒球7号位
    图片点击出现边框样式(一图出现边框,其他图取消边框)
    K8S集群进行分布式负载测试
    代码随想录算法训练营第六十二天| 84.柱状图中最大的矩形
    毅速引领模具3D打印材料创新之路
    《QT从基础到进阶·二十五》界面假死处理
    10 【Express基本使用】
    mysql语句心得
  • 原文地址:https://blog.csdn.net/jiangchufeng123/article/details/134324082