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