poj 2553 tarjian+缩点。。。强连通分量

来源:互联网 发布:php实例代码 编辑:程序博客网 时间:2024/06/08 10:12
//强连通分量为搜索树中的一颗子树//stack自定义栈,dfn(u)为结点u的次序编号//low(u)为u或u的子树能够追溯到的最早的栈中结点的次序号//belong[u]为u所属连通分量#include<iostream>#include<string.h>#include<algorithm>#include<string>#define N 5005using namespace std;bool istack[N];int stack[N],dfn[N],low[N],belong[N],head[N],out[N];typedef struct str{ int to;   int next;}Node;Node node[N*3];int top,num,res,index,n;void init(){ memset(head,-1,sizeof(head));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(out,0,sizeof(out));memset(istack,false,sizeof(istack));num=top=res=0;index=1;}void dfs(int i){dfn[i]=low[i]=index++; stack[top++]=i; istack[i]=true; for(int j=head[i];j!=-1;j=node[j].next) {  int v=node[j].to;  if(!dfn[v])  {  dfs(v);  if(low[v]<low[i]) low[i]=low[v];  }  else if(istack[v]&&dfn[v]<low[i])   low[i]=dfn[v]; } int u; if(dfn[i]==low[i])//回溯,以i为根的搜索子树上的所有结点是一个强连通分量 {    res++; do{  u=stack[--top];  istack[u]=false;  belong[u]=res; }while(i!=u);}}void tarjan(){for(int i=1;i<=n;++i)if(!dfn[i]) dfs(i);}void solve()//缩点{for(int i=1;i<=n;++i){for(int j=head[i];j!=-1;j=node[j].next)if(belong[i]!=belong[node[j].to]){out[belong[i]]++;break;}}for(int i=1;i<=n;++i)if(!out[belong[i]])cout<<i<<" ";        cout<<endl;}int main(){   int m;while(cin>>n>>m&&n){init();for(int i=0;i!=m;++i){  int a,b;    cin>>a>>b;node[num].to=b;node[num].next=head[a];head[a]=num++;}tarjan();solve();}return 0;}

原创粉丝点击