tarjan求强连通分量

#include<bits/stdc++.h>
using namespace std;
int a,b,c,d;
//----------------------------------------------------------------------------------
int head[1000001];
int cnt;
struct node{
	int nxt,to;
	void read()
	{
		int u,v;
		scanf("%d%d",&u,&v);
		cnt++,to=v,nxt=head[u],head[u]=cnt;
	}
} e[1000001];
void debug(int n)
{
	for(int i=head[n];i;i=e[i].nxt)
	cout<<n<<"-->"<<e[i].to<<endl;
}
//----------------------------------------------------------------------------------
int s[1000001],top;
int aa[1000001],ans;
bool an[1000001];
int dfn[1000001],low[1000001];
int shi;
bool vis[1000001];
void tarjan(int u)
{
	s[++top]=u;
	vis[u]=true;
	dfn[u]=low[u]=top;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(vis[v])
		{
			low[u]=min(low[u],dfn[v]);
		}
	}
//	cout<<"answer:";
	if(low[u]==dfn[u])
	{
		int k;
		do
		{
			k=s[top];
			aa[++ans]=s[top];
			cout<<s[top]<<" ";
			top--;
			vis[k]=false;
		}
		while(k!=u);
		cout<<endl;
	}
//	cout<<"debug(vis):";for(int i=1;i<=a;++i) cout<<vis[i]<<" ";cout<<endl;
//	cout<<"debug(low):";for(int i=1;i<=a;++i) cout<<low[i]<<" ";cout<<endl;
//	cout<<"debug(dfn):";for(int i=1;i<=a;++i) cout<<dfn[i]<<" ";cout<<endl;
}
int main()
{
	scanf("%d%d",&a,&b);
	for(int i=1;i<=b;++i) e[i].read();
//	for(int i=1;i<=a;++i) debug(i);
	for(int i=1;i<=a;++i)
	if(!dfn[i])
	{
//		memset(aa,0,sizeof(aa));ans=0;
		tarjan(i);
//		if(ans>1) for(int i=1;i<=ans;++i) an[aa[i]]=true;
	}
//	for(int i=1;i<=a;++i)
//	if(an[i]==true) cout<<'T'<<endl;
//	else cout<<'F'<<endl;
	return 0;
}
/*
4 6
1 2
2 3
4 1
3 1
1 3
2 3
*/ 
原文地址:https://www.cnblogs.com/zhnzh/p/13393533.html