The Bottom of a Graph 强接通分量加缩点
The Bottom of a Graph 强连通分量加缩点
/*题意比较晦涩,大致就是求一个图缩点后出度为0的点的个数。*/ #include <stdio.h> #include <cstring> #include <vector> #include <iostream> using namespace std; vector<int> e[5010]; int dfn[5001]; int low[5001]; int stack[5001]; bool instack[5001]; int belong[5001]; int out[5001]; int n,m,num,top,cnt; void tarjan(int u) { int j; stack[top++]=u; low[u]=dfn[u]=++num; instack[u]=true; for(int i=0; i<e[u].size(); i++) { int v=e[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[v],low[u]); } else if(instack[v]) low[u]=min(dfn[v],low[u]); } if(low[u]==dfn[u]) { cnt++; do { j=stack[--top]; instack[j]=false; belong[j]=cnt; } while(j!=u); } } int main() { while(scanf("%d",&n)==1) { if(n==0) break; scanf("%d",&m); int a,b; for(int i=1; i<=n; i++) e[i].clear(); top=0; num=0; cnt=0; while(m--) { scanf("%d%d",&a,&b); e[a].push_back(b); } memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(instack,false,sizeof(instack)); memset(belong,0,sizeof(belong)); for(int i=1; i<=n; i++) { out[i]=0; if(!dfn[i]) tarjan(i); } for(int i=1; i<=n; i++) { int len=e[i].size(); for(int j=0; j<len; j++) { if(belong[i]!=belong[e[i][j]]) out[belong[i]]++; } } int k=0; for(int i=1; i<=n; i++) { if(out[belong[i]]==0) { if(k++) printf(" "); printf("%d",i); } } printf("\n"); } return 0; }