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 | percentile w ε V :( v → w) percentile (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. Give you a directed graph to locate the points that meet the following conditions and output them from small to large by sequence number. Condition: For a vertex V in the graph, w can reach v for each vertex w in the graph. Of course, if v cannot reach other vertices, such v meets the conditions. Solution: first use tarjan to scale down the vertex, and then calculate the vertex with a degree of 0. See the Code:
<SPAN style = "FONT-SIZE: 18px "> # include <iostream> # include <cstring> # include <string> # include <cmath> # include <cstdio> # include <queue> # include <algorithm> # include <set> # include <vector> # define mem (, b) memset (a, B, sizeof (a) using namespace std; const int MAXN = 5005; vector <int> vert [MAXN]; vector <int> f [MAXN]; // counts the vertex set <int> ans contained in each strongly connected component; // records the points that meet the conditions, by default, the elements in set are int n, m; bool vis [MAXN]; in T dfn [MAXN]; int low [MAXN]; int id [MAXN]; int d [MAXN]; // calculate the degree of output of each strongly connected component int stap [MAXN]; int top; bool inq [MAXN]; int tmpdfn; int fz; void clr () {ans. clear (); mem (vis, 0); mem (dfn, 0); mem (low, 0); mem (id,-1); mem (d, 0 ); mem (inq, 0); mem (stap,-1); tmpdfn = 0; top =-1; fz = 0; int I; for (I = 1; I <= n; I ++) {vert [I]. clear (); f [I]. clear () ;}} void tarjan (int u) {vis [u] = 1; Stap [++ top] = u; inq [u] = 1; dfn [u] = low [u] = ++ tmpdfn; int I; for (I = 0; I <vert [u]. size (); I ++) {int v = vert [u] [I]; if (! Vis [v]) {tarjan (v); low [u] = min (low [u], low [v]);} else if (inq [v]) {low [u] = min (low [u], dfn [v]) ;}} if (low [u] = dfn [u]) {fz ++; int tmp; do {tmp = stap [top --]; id [tmp] = fz; f [fz]. push_back (tmp); inq [tmp] = false;} while (tmp! = U) ;}} void init () {clr (); int I; for (I = 0; I <m; I ++) {int a, B; scanf ("% d", & a, & B); vert [a]. push_back (B) ;}} void solve () {int I; for (I = 1; I <= n; I ++) {if (! Vis [I]) tarjan (I);} int j; for (I = 1; I <= n; I ++) {for (j = 0; j <vert [I]. size (); j ++) {int x, y; x = id [I]; y = id [vert [I] [j]; if (x! = Y) {d [x] ++ ;}}for (I = 1; I <= fz; I ++) {if (d [I] = 0) {for (j = 0; j <f [I]. size (); j ++) {ans. insert (f [I] [j]) ;}}} set <int >:: iterator it; int sum = 0; for (it = ans. begin (); it! = Ans. end (); ++ it) {printf ("% d", * it); if (sum <ans. size ()-1) putchar (''); sum ++;} puts (" ") ;}int main () {while (scanf (" % d ", & n )! = EOF) {if (n = 0) break; scanf ("% d", & m); init (); solve () ;}return 0 ;} </SPAN>