图论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());
    }
}
相关推荐
zc.ovo1 天前
Kruskal重构树
数据结构·c++·算法·重构·图论
qq_574656253 天前
java-代码随想录第66天|Floyd 算法、A * 算法精讲 (A star算法)
java·算法·leetcode·图论
JuneXcy8 天前
C++知识点总结用于打算法
c++·算法·图论
啊我不会诶8 天前
23ICPC澳门站补题
算法·深度优先·图论
qq_574656259 天前
java代码随想录day50|图论理论基础
java·算法·leetcode·图论
YSRM12 天前
Leetcode+Java+图论+岛屿问题
java·算法·leetcode·图论
失散1314 天前
软件设计师——03 数据结构(下)
数据结构·软考·图论·软件设计师
YA10JUN14 天前
C++版搜索与图论算法
c++·算法·图论
蒙奇D索大15 天前
【数据结构】图论核心应用:关键路径算法详解——从AOE网到项目管理实战
数据结构·笔记·学习·考研·算法·图论·改行学it
钮钴禄·爱因斯晨17 天前
数据结构|图论:从数据结构到工程实践的核心引擎
c语言·数据结构·图论