POJ 2553 The Bottom of a Graph

来源:互联网 发布:淘宝怎么开店好赚钱呢 编辑:程序博客网 时间:2024/05/15 23:48
http://poj.org/problem?id=2553
The Bottom of a Graph
Time Limit: 3000MSMemory Limit: 65536KTotal Submissions: 9130Accepted: 3789

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 vv 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.POJ 2553 The Bottom of a Graph - 风未定 - NGUNAUJ

Sample Input

3 31 3 2 3 3 12 11 20

Sample Output

1 32

Source

Ulm Local 2003
tarjan +缩点  统计scc图中出度为0的顶点,并把这些顶点所包含的点的值 按升序输出;
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#include <stack>
#define maxn 5500
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
#define INF 1<<30
const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b)
{
return a>b;
}
vector<int>G[maxn];
stack<int>s;
int n;
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
int a[maxn];
void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_clock;
s.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
dfs(v);
lowlink[u]=min(lowlink[u],lowlink[v]);
}
else if(!sccno[v])lowlink[u]=min(lowlink[u],pre[v]);
}
if(lowlink[u]==pre[u])
{
scc_cnt++;
for(;;)
{
int x=s.top();s.pop();
sccno[x]=scc_cnt;
if(x==u)break;
}
}
}
void find_scc(int n)
{
dfs_clock=scc_cnt=0;
cle(pre),cle(sccno);
for(int i=1;i<=n;i++)
if(!pre[i])dfs(i);
}
void solve()
{
find_scc(n);
int outdegree[maxn];
cle(outdegree);
for(int i=1;i<=n;i++)
for(int j=0;j<G[i].size();j++)
{
int k=G[i][j];
if(sccno[i]!=sccno[k])
{
outdegree[sccno[i]]++;
}
}
cle(a);
int p=0;
for(int i=1;i<=scc_cnt;i++)
if(outdegree[i]==0)
{
for(int j=1;j<=n;j++)
if(sccno[j]==i)
a[p++]=j;
}
sort(a,a+p);
for(int i=0;i<p;i++)
{
printf("%d",a[i]);
if(i==p-1)printf("\n");
else printf(" ");
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
//freopen("out.txt","w",stdout);
int m,a,b;
while(scanf("%d",&n))
{
if(n==0)break;
for(int i=0;i<maxn;i++)
G[i].clear();
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
G[a].push_back(b);
}
solve();
}
return 0;
}

0 0