题目链接:http://poj.org/problem?id=2553
题解:A node v in a graph G=(V,E) is called a sink, if for every node w in G that is reachable from v, v is also reachable from w. The bottom of a graph is the subset of all nodes that are sinks, 强连通分量,出度为0,即为答案。
#include <stdio.h> #include <string.h> #define MAXN 5001 struct node { int to,next; }edge[100000]; int n,belong[MAXN],outdegree[MAXN]; int head[MAXN],instack[MAXN],low[MAXN],dfn[MAXN]; int stack[MAXN],tot,Dindex,top,Bcnt; void Init() {//初始化 tot=0,top=0,Dindex=0,Bcnt=0; memset(head,-1,sizeof(head)); memset(instack,0,sizeof(instack)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belong,0,sizeof(belong)); memset(outdegree,0,sizeof(outdegree)); } int Scan() { char ch; int ret=0; while((ch=getchar())<'0'||ch>'9'); while(ch>='0'&&ch<='9') { ret=ret*10+(ch-'0'); ch=getchar(); } return ret; } void addEdge(int from,int to) { edge[tot].to=to; edge[tot].next=head[from]; head[from]=tot++; } void Tarjan(int x) { int i,u,v; dfn[x]=low[x]=++Dindex; stack[top++]=x; instack[x]=1; for(i=head[x];i!=-1;i=edge[i].next) { u=edge[i].to; if(!dfn[u]) { Tarjan(u); low[x]=low[x]>low[u]?low[u]:low[x]; } else if(instack[u]&&low[x]>dfn[u]) low[x]=dfn[u]; } if(low[x]==dfn[x]) { Bcnt++; do { v=stack[--top]; instack[v]=0; belong[v]=Bcnt; } while (x!=v); } } int main() { int n,e,v,u,i,j; while((n=Scan())&&n) { e=Scan(); Init(); while(e--) { v=Scan(); u=Scan(); addEdge(v,u); } for(i=1;i<=n;++i) { if(!dfn[i]) Tarjan(i); } for(i=1;i<=n;++i) { for(j=head[i];j!=-1;j=edge[j].next) { v=edge[j].to; if(belong[i]!=belong[v]) outdegree[belong[i]]++; } } v=0; for(i=1;i<=n;++i) { if(!outdegree[belong[i]]) { if(!v) { printf("%d",i); v=1; } else printf(" %d",i); } } printf("\n"); } return 0; }