標籤:package 相互 oid cte static max bsp target connected
目錄
1 問題描述
2 解決方案
1 問題描述
引用自百度百科:
如果兩個頂點可以相互連達,則稱兩個頂點強連通(strongly connected)。如果有向圖G的每兩個頂點都強連通,稱G是一個強連通圖。有向圖的極大強連通子圖,稱為強連通分量(strongly connected components)。
Tarjan演算法是基於對圖深度優先搜尋的演算法,每個強連通分量為搜尋樹中的一棵子樹。搜尋時,把當前搜尋樹中未處理的節點加入一個堆棧,回溯時可以判斷棧頂到棧中的節點是否為一個強連通分量。定義DFN(u)為節點u搜尋的次序編號(時間戳記),Low(u)為u或u的子樹能夠追溯到的最早的棧中節點的序號。當DFN(u)=Low(u)時,以u為根的搜尋子樹上所有節點是一個強連通分量。
2 解決方案
下面代碼所使用圖:
具體代碼如下:
package com.liuzhen.practice;import java.util.ArrayList;import java.util.Scanner;import java.util.Stack;public class Main { public static int MAX = 100; public static int count; //用於對圖中頂點遍曆的次序進行計數 public static int n; public static int[] DFN = new int[MAX]; //記錄圖中每個節點的DFS遍曆的時間戳記(即次序) public static int[] Low = new int[MAX]; //記錄每個頂點的所在樹的根節點編號 public static boolean[] inStack = new boolean[MAX]; //用於記錄當前節點是否在棧中 public static Stack<Integer> stack; public void init(int n) { count = 0; stack = new Stack<Integer>(); for(int i = 0;i <= n;i++) { DFN[i] = -1; //代表頂點i未被遍曆 Low[i] = -1; inStack[i] = false; } } static class edge { public int a; //邊的起點 public int b; //邊的終點 edge(int a, int b) { this.a = a; this.b = b; } } public void dfs(ArrayList<edge>[] map, int start) { DFN[start] = count++; Low[start] = DFN[start]; stack.push(start); inStack[start] = true; int j = start; for(int i = 0;i < map[start].size();i++) { j = map[start].get(i).b; if(DFN[j] == -1) { //頂點j未被遍曆 dfs(map, j); Low[start] = Math.min(Low[start], Low[j]); } else if(inStack[j]) { Low[start] = Math.min(Low[start], DFN[j]); } } if(DFN[start] == Low[start]) { System.out.print("強連通分量:"); do { j = stack.pop(); System.out.print(j+" "); inStack[j] = false; } while(start != j); System.out.println(); } return; } public static void main(String[] args) { Main test = new Main(); Scanner in = new Scanner(System.in); n = in.nextInt(); test.init(n); int k = in.nextInt(); //有向圖的邊數目 @SuppressWarnings("unchecked") ArrayList<edge>[] map = new ArrayList[n + 1]; for(int i = 0;i <= n;i++) map[i] = new ArrayList<edge>(); in.nextLine(); for(int i = 0;i < k;i++) { int a = in.nextInt(); int b = in.nextInt(); map[a].add(new edge(a, b)); } test.dfs(map, 1); }}
運行結果:
681 21 32 43 43 54 14 65 6強連通分量:6 強連通分量:5 強連通分量:3 4 2 1
參考資料:
1.有向圖強連通分量的Tarjan演算法
演算法筆記_144:有向圖強連通分量的Tarjan演算法(Java)