有向圖強連通分量:在有向圖g中,如果兩個頂點vi,vj間(vi>vj)有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通。如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量。
tarjan 演算法是基於對圖優先搜素的演算法 , 每個強連通分量為搜尋樹中的一棵子樹 .搜尋時,把當前搜尋樹中未處理的節點加入乙個堆疊 ,回溯時可以判斷棧頂到棧中節點是否為乙個強連通分量 .
定義 dfn[u] 為節點u搜尋的次序編號(時間戳) ,low[u] 為u 或u的子樹能夠追溯到的最早的棧中節點的次序號 .
當dfn[u] = low[u] 時 , 以 u 為根的搜尋子樹上所有節點時乙個強連通分量 , 偽** :
演算法流程 :
模板 :
鄰接表存圖
#include #include #include #include #include #include #include #include using namespace std;
const int max = 10010 ;
vector g[max] ;
int color[max] ;
int dfn[max] ; // 表示dfs時第幾個被搜到的
int low[max] ; // 表示這個點以及其子孫節點連的所有點中dfn最小的值
int stack[max] ; //當前所有可能能構成強連通分量的點
int vis[max] ; // 標記
int cnt[max] ;
int deep ,top , n , m, sum , ans ;
void tarjan(int u )
} cout鏈式前向星
#include #include #include #include #include #include #include #include #include using namespace std;
const int max = 100100 ;
int n , m , idx ;
int cnt ,bcnt ;
int head[max] ;
int vis[max] ;
int dfn[max] ,low[max] ;
int belong[max] ;
stacks ;
struct edgee[max] ;
void add(int u , int v)
void tarjan(int u )
else
} }if(dfn[u] == low[u])while(u!=v) ; }
}int main()
for(int i = 1 ; i<=n ; i++)
}// cout<1)
} cout<
return 0;
}
強連通分量Tarjan演算法
o v e 通常的tarjan寫法是有個dfn陣列跟乙個instack陣列,我精簡了下 把這兩個陣列都刪去了,用更簡便的寫法代替,也省了空間。int low maxn 記錄這棵樹能到達的最早祖先 其實不一定是最早,但不影響使用 int time 時間戳 int num 連通分量的個數 int bel...
強連通分量 tarjan演算法
強連通分量 tarjan演算法 有向圖強連通分量 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected com...
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...