1. 程式人生 > 其它 >341 強連通分量 Tarjan 演算法

341 強連通分量 Tarjan 演算法

視訊連結:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int N=10010;
int n,m,a,b;
vector<int> e[N]; 
int dfn[N],low[N],tot;
int stk[N],instk[N],top;
int scc[N],siz[N],cnt;

void tarjan(int x){
  dfn[x]=low[x]=++tot;
  stk[
++top]=x,instk[x]=1; // printf("dfn[%d]=%d\n",x,dfn[x]); for(int y : e[x]){ if(!dfn[y]){//若y尚未訪問 tarjan(y);//// low[x]=min(low[x],low[y]); // printf(" low[%d]=%d\n",x,low[x]); } else if(instk[y]){//若y已訪問且在棧中 low[x]=min(low[x],dfn[y]); // printf(" *low[%d]=%d\n",x,low[x]);
} } if(dfn[x]==low[x]){//若x是SCC的根 int y; ++cnt; printf("SCC: "); do{ y=stk[top--]; instk[y]=0; scc[y]=cnt; //y屬於哪個SCC ++siz[cnt];//當前SCC的大小 printf("%d ",y); }while(y!=x); puts(""); } } int main(){ cin>>n>>m; while(m--){ cin>>a>>b, e[a].push_back(b); }
for(int i=1; i<=n; i++)//可能不連通 if(!dfn[i]) tarjan(i); return 0; } /* 9 13 1 2 1 4 2 3 3 1 4 5 4 9 5 6 5 7 6 7 6 8 8 5 8 7 9 3 */