图论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());
    }
}
相关推荐
罗湖老棍子19 小时前
【模板】并查集(洛谷P3367)
算法·图论·并查集
wanderist.21 小时前
C++输入输出的一些问题
开发语言·c++·图论
Snow_day.2 天前
有关排列排列组合(1)
数据结构·算法·贪心算法·动态规划·图论
初晴や3 天前
【C++】图论:基础理论与实际应用深入解析
c++·算法·图论
闻缺陷则喜何志丹3 天前
【图论 DFS 换根法】3772. 子图的最大得分|2235
c++·算法·深度优先·力扣·图论·换根法
君义_noip4 天前
信息学奥赛一本通 2134:【25CSPS提高组】道路修复 | 洛谷 P14362 [CSP-S 2025] 道路修复
c++·算法·图论·信息学奥赛·csp-s
罗湖老棍子5 天前
信使(msner)(信息学奥赛一本通- P1376)四种做法
算法·图论·dijkstra·spfa·floyd·最短路算法
修炼地5 天前
代码随想录算法训练营第五十三天 | 卡码网97. 小明逛公园(Floyd 算法)、卡码网127. 骑士的攻击(A * 算法)、最短路算法总结、图论总结
c++·算法·图论
罗湖老棍子6 天前
【例4-6】香甜的黄油(信息学奥赛一本通- P1345)
算法·图论·dijkstra·floyd·最短路算法·bellman ford
--JR7 天前
015——图(1.图的相关概念与存储)
数据结构·c++·算法·链表·图论