模板——tarjan算法(缩点)

n个点,m条有向边(color相同的就可以缩成一个点了)

#include<bits/stdc++.h>
using namespace std;
int n,m,jump[100005],dfn[100005],low[100005],dfn_num=0,stack[100005]={0},top=0;
int color[100005],col_num=0,sta[100005];
bool judge[100005]={0};
struct nob{
	int nex,to;
}a[100005];
void Tarjan(int x){
	dfn[x]=++dfn_num;
	low[x]=dfn_num;
	judge[x]=true;
	sta[++top]=x;
	for (int i=jump[x]; i; i=a[i].nex){
		int tem=a[i].to;
		if (!dfn[tem]){
			Tarjan(tem);
			low[x]=min(low[x],low[tem]);
		}
		else if (judge[tem]) low[x]=min(low[x],dfn[tem]);
	}
	if (dfn[x]==low[x]){
		judge[x]=false;
		color[x]=++col_num;
		while (sta[top]!=x){
			color[sta[top]]=col_num;
			judge[sta[top--]]=false;
		}
		top--;
	}
}
int main(){
	cin>>n>>m;
	for (int i=1,x,y; i<=m; i++){
		cin>>x>>y;
		a[i].to=y;
		a[i].nex=jump[x];
		jump[x]=i;
	}
        for(int i=1; i<=n; i++)
        if (!dfn[i])//图中可能会有多个部分
	Tarjan(i);
	return 0;
}
原文地址:https://www.cnblogs.com/cain-/p/7701606.html