No1.Tarjan求強連通分量
阿新 • • 發佈:2018-12-18
本文不適合用於學習!!!只是一份模板(可能還是很爛的模板
頹了近一個月猛然發現要比賽了,終於下定決心用寫部落格的方式來幫自己整理複習。當然我也只是個混了一個月的蒟蒻,學過的東西相當有限,只希望自己能堅持下去吧......
那麼就從我上週學的tarjan開始!
//求一張n個點、m條邊的圖中的聯通分量並列印結果 #include<cstdio> #include<stack> #include<algorithm> using namespace std; const int MAXN = 10005; const int MAXM = 50005; int n,m; struct Edge{ int next,to;//next指的是下一條邊 }edge[MAXM]; int head[MAXN],cnt; void addedge(int from,int to){ edge[++cnt].next = head[from]; edge[cnt].to = to; head[from] = cnt; } int dfn[MAXN],low[MAXN],tme,instack[MAXN]; stack<int> zhan; void tarjan(int x){ dfn[x] = low[x] = ++tme; instack[x] = 1; zhan.push(x); for(int i = head[x];i;i = edge[i].next){ int y = edge[i].to; if(instack[y] == 0) {tarjan(y);low[x] = min(low[x],low[y]);} else if(instack[y] == 1) low[x] = min(low[x],dfn[y]);//這兩句的差別不是很懂,姑且死記硬背吧 } if(low[x] == dfn[x]){ while(!zhan.empty()){ int m = zhan.top(); printf("%d ",m); zhan.pop(); if(m == x) break; } printf("\n"); } } int main(){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ int x,y; scanf("%d%d",&x,&y); addedge(x,y); } for(int i = 1;i <= n;i++) if(!dfn[i]) tarjan(i);//這是為了防止整個圖不連通 return 0; }