無向連通圖中“割邊”、“關(guān)鍵橋”問題的Java實現(xiàn)

同割點問題(參見我的上一篇博客)類似,割點問題(也叫關(guān)鍵橋問題)描述的是在無向圖中,倘若去掉某條邊之后,原連通圖被分割為兩個不可達的圖,則該條邊就是所謂的割邊。跟割點唯一不同的就是原本low[v] >= num[u]的判定條件變?yōu)榱薼ow[v] > num[u],也就是要滿足子節(jié)點v現(xiàn)在連父節(jié)點u都不能到達,那么兩節(jié)點組成的邊就是割邊!代碼:

package cut.edge;

import java.util.Scanner;

/**
 * "轟炸重要橋"問題:
 * 關(guān)鍵詞:DFS、割邊、無向連通圖、關(guān)鍵橋
 * @author XZP
 *一組測試數(shù)據(jù):
6 6 
1 4 
1 3 
4 2
3 2
2 5 
5 6
 */
public class BombingImportantBridge {
    public static int index; // 時間戳
    public static void main(String[] args) {
        int INF = 99999; // 人為設定的最大值
        int i, j; // 游標
        int v1, v2; // 暫存頂點編號
        int root; // 根節(jié)點的編號
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 頂點數(shù)
        int m = sc.nextInt(); // 邊的條數(shù)
        // 存儲邊的數(shù)組
        int[][] edges = new int[n + 1][n + 1];
        int[] num = new int[n + 1]; // 存儲第一遍dfs遍歷的時間戳
        int[] low = new int[n + 1]; // 存儲最小時間戳的數(shù)組
        // 輸入邊的信息
        for (i = 1; i<= m; i++) {
            v1 = sc.nextInt();
            v2 = sc.nextInt();
            edges[v1][v2] = 1;
            edges[v2][v1] = 1;
        }
        root = 1;
        dfs(1, root, low, num, n, edges);
        
    }
    /**
     * 深度優(yōu)先求“割邊”
     * @param child
     * @param father
     * @param low
     * @param num
     * @param n
     * @param edges
     */
    public static void dfs(int child, int father, int[] low, int[] num, int n, int[][] edges) {
        int i, j;
        index++;
        num[child] = index;
        low[child] = index;
        for (i = 1; i <= n; i++) {
            if (edges[child][i] == 1) {
                if (num[i] == 0) {
                    dfs(i, child, low, num, n, edges);
                    low[child] = min(low[i], low[child]);
                    if (low[i] > num[child]) { // 關(guān)鍵步驟,跟割點差不多,只是這里沒有等號,表示不經(jīng)過父節(jié)點,該點就不能達到祖先(包括父節(jié)點)那兩點組成的邊即割邊
                        System.out.println("割邊為 " + child + " - " + i);
                    }
                } else if (i != father) {
                    low[child] = min(low[child], num[i]);
                }
            }
        }
    }
    /**
     * 求兩個數(shù)中的較小值
     * @param a
     * @param b
     * @return
     */
    public static int min(int a, int b) {
        return a > b ? b : a;
    }
}

//***********實踐證明:這種存儲方式在某些情況下比較優(yōu)化,但是由于dfs便于找到下一個頂點,最好還是用鄰接矩陣*******************
/**
 * 表示一條邊的對象
 * @author XZP
 *
 */
class Edge {
    private int v1;
    private int v2;
    public Edge(int v1, int v2) {
        this.v1 = v1;
        this.v2 = v2;
    }
    // getter
    public int getV1() {
        return v1;
    }
    public int getV2() {
        return v2;
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 深度優(yōu)先搜索 在圖中搜索的一般過程為: 記錄當前結(jié)點被發(fā)現(xiàn)的時間(discovery time) 遍歷訪問未被訪問...
    njzwj閱讀 1,883評論 0 0
  • 目錄 1.圖的表示 2.廣度優(yōu)先搜索 3.深度優(yōu)先搜索——本質(zhì)等同于回溯 4.拓撲排序 5.強連通分量 1.圖的表...
    王偵閱讀 4,499評論 0 8
  • 雙連通分量 點_雙連通分量 BCC對于一個連通圖,如果任意兩點至少存在兩條“點不重復”的路徑,則說圖是點雙連通的(...
    Gitfan閱讀 2,249評論 0 0
  • 前言:我們偉大的BAT承載了多少程序員的夢想,到底有多少人的向往... 然而這個“T”的面試也是經(jīng)常不走尋常路,最...
    Tel_小超閱讀 1,209評論 0 0
  • 很榮幸能來長投學習理財?shù)闹R,班班熙熙和各位學姐都是我學習的榜樣,很希望能和他們一樣,讓錢生錢,讓錢為我賺錢,其實...
    晨光_dabe閱讀 127評論 1 0

友情鏈接更多精彩內(nèi)容