同样利用了dfn:dfs序,low:能回到的最早祖先的dfn;
废话少说 上板子
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<stack>//栈的stl需要头文件 #include<set> using namespace std; sstack<int>s;//定义该栈 int n,m,a,b; struct data{ int to,nxt; }edge[200000*2+1]; int sum,tot,len,tag,sig; bool vis[100001]; int low[100001],dfn[100001],head[100001]; bool ans[100001]; void add(int from,int to){ edge[++sum].nxt=head[from]; head[from]=sum; edge[sum].to=to; } int comp(const data1&a,const data1&b){return a.st<b.st;} void Tarjan(int now){ s.push(now);//压入栈 vis[now]=true;//表示在栈中 dfn[now]=low[now]=++tot;//时间戳,low值初始化 for(int i=head[now];i;i=edge[i].nxt){//同样链式前向星 int to=edge[i].to; if(!dfn[to]){ Tarjan(to); low[now]=min(low[to],low[now]);//更新low } else if(vis[to])low[now]=min(low[now],dfn[to]);//在栈中,需更新 } if(dfn[now]==low[now]){ int u=-1; int ll=answer[++tag].l=len+1;//对输出值排序 while(u!=now){ u=s.top(); vis[u]=false;//表示已经出栈 ans[++len]=u; s.pop();//同上 } int rr=answer[tag].r=len; sort(ans+ll,ans+rr+1);//这里只是对输出强连通分量个数及其元素起作用 answer[tag].st=ans[ll]; } } void print(){ printf("%d ",tag); sort(answer+1,answer+tag+1,comp); for(int i=1;i<=tag;++i) { for(int j=answer[i].l;j<=answer[i].r;++j) printf("%d ",ans[j]); printf(" "); } return; } int main(){ scanf("%d",&n); while(scanf("%d%d",&a,&b)!=EOF)add(a,b); for(int i=1;i<=n;++i) if(!dfn[i])Tarjan(i);//若有一部分不与其他相连接 print(); return 0; }