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;
}