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.
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
这个题把我弄晕了,不知道是每个强连通分量各自输出还是一起输出,还是只输出一个,可能是我英语不好,但是,我读的题目就是这样的,样例也不指明,WA的几次啊
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; int outdegree[10000+10]; struct SCC { static const int maxn=10000+10; vector<int>group[maxn],scc[maxn]; int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt,n,m; stack<int>S; void init() { for (int i=0;i<=n;i++) group[i].clear(); } void addedge(int from,int to) { group[from].push_back(to); } void dfs(int u) { pre[u]=lowlink[u]=++dfs_clock; S.push(u); for (int i=0;i<group[u].size();i++) { int v=group[u][i]; if (!pre[v]) { dfs(v); lowlink[u]=min(lowlink[u],lowlink[v]); } else if (!sccno[v]) { lowlink[u]=min(lowlink[u],pre[v]); } } if (lowlink[u]==pre[u]) { scc_cnt++; scc[scc_cnt].clear(); while (1) { int x=S.top(); S.pop(); scc[scc_cnt].push_back(x); sccno[x]=scc_cnt; if (x==u) break; } } } void find_scc() { dfs_clock=scc_cnt=0; memset(pre,0,sizeof(pre)); memset(sccno,0,sizeof(sccno)); for (int i=1;i<=n;i++) if (!pre[i]) dfs(i); } }; SCC table; int main() { int a[10000+10],x,y; while (scanf("%d",&table.n)!=EOF && table.n) { scanf("%d",&table.m); table.init(); for (int i=0;i<table.m;i++) { scanf("%d%d",&x,&y); table.addedge(x,y); } table.find_scc(); for (int i=1;i<=table.scc_cnt;i++) outdegree[i]=0; for (int u=1;u<=table.n;u++) { for (int i=0;i<table.group[u].size();i++) { int v=table.group[u][i]; if (table.sccno[u]!=table.sccno[v]) outdegree[table.sccno[u]]++; } } int k=0; for (int i=1;i<=table.scc_cnt;i++) { if (outdegree[i]==0) { for (int j=0;j<table.scc[i].size();j++) { a[k++]=table.scc[i][j]; } //break; } } sort(a,a+k); printf("%d",a[0]); for (int i=1;i<k;i++) printf(" %d",a[i]); printf(" "); } return 0; }