341 強連通分量 Tarjan 演算法
阿新 • • 發佈:2022-05-28
視訊連結:
#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 */