POJ 2553 The Bottom of a Graph

The Bottom of a Graph

Time Limit: 3000ms
Memory Limit: 65536KB
This problem will be judged on  PKU. Original ID: 2553
64-bit integer IO format: %lld      Java class name: Main
 
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,  epairs 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
 

Sample Input

3 3

1 3 2 3 3 1

2 1

1 2

0

Sample Output

1 3

2

Source

 
解题:求这样的点,它能到的点,那点也可以到它,注意先后顺序。然后求强联通缩点,出度为0的集合,里面的点即为我们求得那些点
 
 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <cmath>

 5 #include <algorithm>

 6 #include <climits>

 7 #include <vector>

 8 #include <queue>

 9 #include <cstdlib>

10 #include <string>

11 #include <set>

12 #include <stack>

13 #define LL long long

14 #define pii pair<int,int>

15 #define INF 0x3f3f3f3f

16 using namespace std;

17 const int maxn = 6000;

18 struct arc {

19     int to,next;

20     arc(int x = 0,int y = -1) {

21         to = x;

22         next = y;

23     }

24 };

25 arc e[maxn*100];

26 int head[maxn],dfn[maxn],low[maxn],belong[maxn],my[maxn];

27 int tot,n,m,top,scc,idx,out[maxn],ans[maxn];

28 bool instack[maxn];

29 void init() {

30     for(int i = 0; i < maxn; ++i) {

31         dfn[i] = low[i] = belong[i] = 0;

32         instack[i] = false;

33         head[i] = -1;

34         out[i] = 0;

35     }

36     scc = tot = idx = top = 0;

37 }

38 void add(int u,int v){

39     e[tot] = arc(v,head[u]);

40     head[u] = tot++;

41 }

42 void tarjan(int u) {

43     dfn[u] = low[u] = ++idx;

44     my[top++] = u;

45     instack[u] = true;

46     for(int i = head[u]; ~i; i = e[i].next) {

47         if(!dfn[e[i].to]) {

48             tarjan(e[i].to);

49             low[u] = min(low[u],low[e[i].to]);

50         } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]);

51     }

52     if(dfn[u] == low[u]) {

53         scc++;

54         int v;

55         do {

56             v = my[--top];

57             instack[v] = false;

58             belong[v] = scc;

59         } while(v != u);

60     }

61 }

62 int main() {

63     int u,v;

64     while(~scanf("%d",&n)&&n) {

65         scanf("%d",&m);

66         init();

67         for(int i = 0; i < m; ++i) {

68             scanf("%d%d",&u,&v);

69             add(u,v);

70         }

71         for(int i = 1; i <= n; ++i)

72             if(!dfn[i]) tarjan(i);

73         for(int i = 1; i <= n; ++i)

74             for(int j = head[i]; ~j; j = e[j].next)

75                 if(belong[i] != belong[e[j].to]) out[belong[i]]++;

76         int cnt = 0;

77         for(int i = 1; i <= n; ++i)

78             if(!out[belong[i]]) ans[cnt++] = i;

79         if(cnt){

80             for(int i = 0; i < cnt; ++i)

81                 printf("%d%c",ans[i],i + 1 == cnt?'\n':' ');

82         }else puts("");

83     }

84     return 0;

85 }
View Code

 

你可能感兴趣的:(Graph)