POJ 2553 The Bottom of a Graph
Description
We will use the following (standard) definitions from graph theory. Let V be a nonempty and finite set, its elements being called vertices (or nodes). Let E be a subset of the Cartesian product V×V, its elements being called edges. ThenG=(V,E) is called a directed graph.
Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1). Then p is called a path from vertex v1 to vertex vn+1 in G and we say that vn+1is reachable from v1, writing (v1→vn+1).
Here are some new definitions. 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, i.e.,bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.
Let n be a positive integer, and let p=(e1,...,en) be a sequence of length n of edges ei∈E such that ei=(vi,vi+1) for a sequence of vertices (v1,...,vn+1). Then p is called a path from vertex v1 to vertex vn+1 in G and we say that vn+1is reachable from v1, writing (v1→vn+1).
Here are some new definitions. 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, i.e.,bottom(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}. You have to calculate the bottom of certain graphs.
Input
The input contains several test cases, each of which corresponds to a directed graph G. Each test case starts with an integer number v, denoting the number of vertices of G=(V,E), where the vertices will be identified by the integer numbers in the set V={1,...,v}. You may assume that 1<=v<=5000. That is followed by a non-negative integer e and, thereafter, e pairs of vertex identifiers v1,w1,...,ve,we with the meaning that (vi,wi)∈E. There are no edges other than specified by these pairs. The last test case is followed by a zero.
Output
For each test case output the bottom of the specified graph on a single line. To this end, print the numbers of all nodes that are sinks in sorted order separated by a single space character. If the bottom is empty, print an empty line.
Sample Input
3 3
1 3 2 3 3 1
2 1
1 2
0
Sample Output
1 3
2
Source
题目大意 : 给你一个图,其中有两点u,v如果u能到达v,v也能到达u,那么这种点称为sink,输出所有sink
思路:u可以到达v,v可以到达u,明显是强连通分量,我们可以用tarjan来求。找到所有出度为0的强连通分量输出
#include<stack> #include<cstdio> #include<cstring> #include<iostream> #define MAXN 500005 using namespace std; int head[MAXN],tot,sum,n,m; int dfn[MAXN],low[MAXN],belong[MAXN],cnt,f[MAXN]; bool vis[MAXN]; struct node { int to; int next; }; node e[MAXN]; stack<int> s; inline void read(int&x) { x=0;int f=1;char c=getchar(); while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();} x=x*f; } inline void MEM() { memset(head,0,sizeof head); memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); for(int i=1;i<=n;i++) { vis[i]=false;belong[i]=0;f[i]=false; } sum=0; } inline void add(int x,int y) { e[++tot].to=y; e[tot].next=head[x]; head[x]=tot; } inline void tarjan(int u) { dfn[u]=low[u]=++cnt; vis[u]=true;s.push(u); for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { sum++; int t; do { t=s.top(); s.pop(); belong[t]=sum; }while(u!=t); } } int main() { int x,y; while(scanf("%d",&n)&&n) { read(m); MEM();cnt=0;tot=0; for(int i=1;i<=m;i++) { read(x);read(y); add(x,y); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) { for(int j=head[i];j;j=e[j].next) if(belong[e[j].to]!=belong[i]) { f[belong[i]]=true; break; } } for(int i=1;i<=n;i++) if(!f[belong[i]]) printf("%d ",i); printf("\n"); while(!s.empty()) s.pop(); } return 0; }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现