图论09-桥和割点

文章目录

  • [1 寻找桥的算法](#1 寻找桥的算法)
  • [2 桥的代码实现](#2 桥的代码实现)
  • [3 寻找割点的算法](#3 寻找割点的算法)
  • [4 割点的代码实现](#4 割点的代码实现)

1 寻找桥的算法





2 桥的代码实现

c 复制代码
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());
    }
}

3 寻找割点的算法


4 割点的代码实现

c 复制代码
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());
    }
}
相关推荐
Fa_Mian_Tuan3 天前
最小生成树之Kruskal算法(超详细原理+完整可运行C语言代码)
c语言·开发语言·数据结构·笔记·算法·图论
rannn_1114 天前
【力扣hot100】图论专题+模板|DFS、BFS、拓扑排序...
java·算法·leetcode·深度优先·图论
Fa_Mian_Tuan4 天前
图论基础 | 邻接多重表原理剖析 + 完整可运行C语言代码(插边/删边/释放)
c语言·数据结构·笔记·算法·图论
疯狂打码的少年4 天前
【数据结构】图的应用:最小生成树(Prim / Kruskal)
数据结构·笔记·算法·图论
Fa_Mian_Tuan6 天前
图论基础|邻接矩阵超详细讲解(含无向/有向/带权图+完整可运行C语言代码)
c语言·数据结构·笔记·算法·图论
有点。7 天前
C++二叉树二(练习题)
数据结构·c++·算法·图论
依然鸣8 天前
PTA团体程序设计天梯赛L1真题讲解L1-077-080
开发语言·c++·算法·深度优先·pat考试·图论
oier_Asad.Chen9 天前
【洛谷题解/AcWing题解/OI学习笔记】洛谷P2868【USACO07DEC】Sightseeing Cows G(01分数规划求最大比率)
算法·图论·spfa·二分·负环
wabs6669 天前
关于图论【A*算法 | 卡码网127.骑士的攻击的思考】
数据结构·算法·图论·卡码网·广搜的改进版
依然鸣10 天前
PTA团体程序设计天梯赛L2真题讲解L2-005-008
开发语言·数据结构·c++·算法·深度优先·pat考试·图论