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 v, v 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
Ulm Local 2003 题目大意 多组数据输入,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 }