您的位置:首页 > 其它

poj 2553 The Bottom of a Graph

2016-09-01 21:11 337 查看
The Bottom of a Graph

Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 10414 Accepted: 4320
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.
Then G=(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+1 is 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

Ulm Local 2003

要理解题意,求的是一种点,凡是这种点可以到达的点,都可以返回该点,也就是求出度为0的连通分量中所有的点,注意输出时,要按照顺序。

知道了定义,题目就很简单了,先做一次tarjan,然后找出度为0的连通分量;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
using namespace std;
const int maxn=5010;
const int maxm=50010;
struct Edge
{
int to,next;
}edge[maxm];
int head[maxn],tot;
void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn];
int Index,top;
int scc;
bool Instack[maxn];
int num[maxn];
void Tarjan(int u)
{
int v;
Low[u]=DFN[u]=++Index;
Stack[top++]=u;
Instack[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!DFN[v])
{
Tarjan(v);
if(Low[u]>Low[v]) Low[u]=Low[v];
}
else if(Instack[v]&&Low[u]>DFN[v])
{
Low[u]=DFN[v];
}
}
if(Low[u]==DFN[u])
{
++scc;
do{
v=Stack[--top];
Instack[v]=false;
Belong[v]=scc;
num[scc]++;
}while(v!=u);
}
}
void solve(int N)
{
memset(DFN,0,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,0,sizeof(num));
Index=scc=top=0;
for(int i=1;i<=N;++i)
{
if(!DFN[i]) Tarjan(i);
}
}
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
int out[maxn];
int main()
{
int v,e;
while(scanf("%d",&v)!=EOF&&v)
{
scanf("%d",&e);
int a,b;
init();
for(int i=0;i<e;++i)
{
scanf("%d %d",&a,&b);
addedge(a,b);
}
solve(v);

memset(out,0,sizeof(out));
for(int i=1;i<=v;++i)
{
for(int j=head[i];j!=-1;j=edge[j].next)
{
if(Belong[i]!=Belong[edge[j].to])
{
out[Belong[i]]++;
}
}
}
for(int i=1;i<=v;++i)
{
if(!out[Belong[i]])
printf("%d ",i);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj tarjan