poj2533 The Bottom of a Graph(Tarjan+缩点)

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 12659   Accepted: 5211

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

Source

 
题目大意
多组数据输入,v个点,e条边,接下来一行是e对有向边,v为0时输入结束
求解最底端的强连通分量,顺序输出
 
思路
用Tarjan算法先缩点,再判断哪些强连通分量的出度为0,升序输出这些强连通分量里面的点的编号
 
 1 #include <cstdio>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N=5e3+5;
 8 int low[N],dfn[N],Stack[N],belong[N],cdu[N];
 9 bool inStack[N];
10 int n,m,tot,tag,top;
11 vector<int> g[N];
12 vector<int> res;
13 
14 void init(){
15     top=tag=0;
16     memset(low,0,sizeof low);
17     memset(dfn,0,sizeof dfn);
18     memset(Stack,0,sizeof Stack);
19     memset(belong,0,sizeof belong);
20     memset(cdu,0,sizeof cdu);
21     memset(inStack,false,sizeof inStack);
22     res.clear();
23     for(int i=0;i<N;i++){
24         g[i].clear();
25     }
26 }
27 
28 void tarjan(int u){
29     int v;
30     low[u]=dfn[u]=++tot;
31     Stack[++top]=u;
32     inStack[u]=true;
33     for(int i=0;i<g[u].size();i++){
34         v=g[u][i];
35         if(dfn[v]==0){
36             tarjan(v);
37             low[u]=min(low[u],low[v]);
38         }
39         else if(inStack[v]==true){
40             low[u]=min(low[u],dfn[v]);
41         }
42     }
43     if(dfn[u]==low[u]){
44         tag++;
45         do{
46             v=Stack[top--];
47             inStack[v]=false;
48             belong[v]=tag;
49         }while(u!=v);
50     }
51 }
52 
53 int main(){
54     while(scanf("%d",&n),n){
55         init();
56         scanf("%d",&m);
57         for(int i=1;i<=m;i++){
58             int x,y;
59             scanf("%d%d",&x,&y);
60             g[x].push_back(y);
61         }
62         for(int i=1;i<=n;i++){
63             if(dfn[i]==0){
64                 tot=0;
65                 tarjan(i);
66             }
67         }
68         for(int i=1;i<=n;i++){
69             for(int j=0;j<g[i].size();j++){
70                 int x=g[i][j];
71                 if(belong[i]!=belong[x]){
72                     cdu[belong[i]]++;
73                 }
74             }
75         }
76 //        for(int i=1;i<=tag;i++){
77 //            printf("%d",i);
78 //            for(int j=0;j<vec[i].size();j++){
79 //                printf(" %d",vec[i][j]);
80 //            }
81 //            printf("\n");
82 //        }
83         for(int i=1;i<=tag;i++){
84             if(cdu[i]>0) continue;
85             for(int j=1;j<=n;j++){
86                 if(belong[j]==i){
87                     res.push_back(j);
88                 }
89             }
90         }
91         sort(res.begin(),res.end());
92         for(int i=0;i<res.size();i++){
93             if(i) printf(" ");
94             printf("%d",res[i]);
95         }
96         printf("\n");
97     }
98 }

 

posted @ 2019-08-28 15:58  Cherlie  阅读(130)  评论(0编辑  收藏  举报