強聯通分量(tarjan模板)

#include<bits/stdc++.h>
using namespace std;
const int N=10010;
const int M=100010;
int timing;
vector<int>G[N];//存邊
int dfn[N];//編號
int low[N];//時間戳
bool ins[N];//判斷是否在棧中
stack<int>s;//棧存強聯通
int colorcnt;//強聯通分量個數
int color[N];//標記每個結點屬於哪個強聯通
int colornum[N];//每個強聯通分量的結點個數
void init(int n){
	for(int i=1;i<=n;i++){
		G[i].clear();
		low[i]=0;
		dfn[i]=0;
	}
	colorcnt=0;
}
void tarjan(int u){
	dfn[u]=low[u]=++timing;
	s.push(u);
	ins[u]=true;
	for(int i=0,j=G[u].size();i<j;i++){
		int v=G[u][i];
		if(dfn[v]==0){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}else if(ins[v]==true){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(dfn[u]==low[u]){
		colorcnt++;
		while(s.top()!=u){
			int tmp=s.top();s.pop();
			ins[tmp]=false;
			color[tmp]=colorcnt;
			colornum[colorcnt]++;
		}
		s.pop();
		ins[u]=false;
		color[u]=colorcnt;
		colornum[colorcnt]++;
	}
}
int main(){
	int n,m,a,b;
	while(scanf("%d %d",&n,&m)!=EOF&&n+m){
		init(n);
		for(int i=0;i<m;i++){
			scanf("%d %d",&a,&b);
			G[a].push_back(b);
		}
		for(int i=1;i<=n;i++){
			if(dfn[i]==0)tarjan(i);
		}
		if(colorcnt==1)printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章