# POJ 2553--The Bottom of a Graph【scc缩点构图 && 求出度为0的scc && 输出scc中的点】

The Bottom of a Graph
 Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9575 Accepted: 3984

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.

Sample Input

3 3
1 3 2 3 3 1
2 1
1 2
0


Sample Output

1 3
2

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxn 5000
#define maxm 5000 * 5000
using namespace std;
int n, m;
struct node{
int u, v, next;
};

node edge[maxm];

int low[maxn], dfn[maxn];
int dfs_clock;
int Stack[maxn], top;
bool Instack[maxn];
int Belong[maxn];
int scc_clock;
int in[maxn], out[maxn];
vector<int>scc[maxn];
int num[maxn];

void init(){
cnt = 0;
}

}

void getmap(){
while(m--){
int a, b;
scanf("%d%d", &a, &b);
}
}

void Tarjan(int u, int per){
int v;
low[u] = dfn[u] = ++dfs_clock;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(!dfn[v]){
Tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(Instack[v])
low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
scc_clock++;
scc[scc_clock].clear();
do{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc_clock;
scc[scc_clock].push_back(v);
}
while( v != u);
}
}

void suodian(){
for(int i = 1; i <= scc_clock; ++i){
out[i] = 0;
}
for(int i = 0; i < cnt; ++i){
int u = Belong[edge[i].u];
int v = Belong[edge[i].v];
if(u != v)
out[u]++;
}
}

void find(){
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(Belong, 0, sizeof(Belong));
memset(Stack, 0, sizeof(Stack));
memset(Instack, false, sizeof(false));
dfs_clock = scc_clock = top = 0;
for(int i = 1; i <= n ; ++i){
if(!dfn[i])
Tarjan(i, i);
}
}

void solve(){
int k = 0;
for(int i = 1; i <= scc_clock; ++i){
if(out[i] == 0){
for(int j = 0; j < scc[i].size(); ++j)
num[k++] = scc[i][j];
}
}
sort(num, num + k);
for(int i = 0; i < k; ++i){
if(!i)
printf("%d", num[i]);
else
printf(" %d", num[i]);
}
printf("\n");
}

int main (){
while(scanf("%d", &n), n){
scanf("%d", &m);
init();
getmap();
find();
suodian();
solve();
}
return 0;
}


• 本文已收录于以下专栏：

举报原因： 您举报文章：POJ 2553--The Bottom of a Graph【scc缩点构图 && 求出度为0的scc && 输出scc中的点】 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)