1. 程式人生 > >No1.Tarjan求強連通分量

No1.Tarjan求強連通分量

本文不適合用於學習!!!只是一份模板(可能還是很爛的模板

頹了近一個月猛然發現要比賽了,終於下定決心用寫部落格的方式來幫自己整理複習。當然我也只是個混了一個月的蒟蒻,學過的東西相當有限,只希望自己能堅持下去吧......

那麼就從我上週學的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;
}