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

梦想的初衷 提交于 2019-11-28 19:51:33
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 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!