The bottom of a graph
| Time limit:3000 Ms |
|
Memory limit:65536 K |
| Total submissions:8904 |
|
Accepted:3689 |
Description
We will use the following (standard) Definitions from graph theory. Let
VBe a nonempty and Finite Set, its elements being called vertices (or nodes). Let
EBe a subset of the Cartesian Product
V × V, Its elements being called edges. Then
G = (V, E)Is called a directed graph.
Let
NBe a positive integer, And let
P = (E1,..., en)Be a sequence of Length
NOf Edges
Ei, ESuch that
Ei = (Vi, vi + 1)For a sequence of vertices
(V1,..., vn + 1). Then
PIs called a path from vertex
V1To Vertex
Vn + 1In
GAnd we say that
Vn + 1Is reachable from
V1, Writing
(V1 → VN + 1).
Here are some new definitions. A node
VIn a graph
G = (V, E)Is called a sink, if for every node
WIn
GThat is reachable from
V,
VIs 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
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
EAnd, thereafter,
EPairs of vertex identifiers
V1, W1,..., VE, weWith 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 31 3 2 3 3 12 11 20
Sample output
1 32
Question meaning:
For a directed graph with n knots and m edges, if any other vertex that a vertex can reach the vertex or a vertex cannot reach another vertex, the vertex is sink, from small to output sink.
Ideas:
This question is difficult in translation, especially the four I took two tests to the people T-T, understand it is very water, first use Tarjan shrink point block, then we can mark the points of the blocks without degree, and finally sort the output.
Code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 #include <queue> 7 #include <stack> 8 using namespace std; 9 10 #define N 500511 int n, m;12 vector<int>ve[N];13 int low[N], dfn[N], dfn_clock;14 int in[N], out[N], instack[N], a[N], b[N];15 int cnt;16 stack<int>st;17 18 void init(){19 int i, j;20 while(!st.empty()) st.pop();21 22 for(i=0;i<=n;i++){23 ve[i].clear();instack[i]=1;24 }25 memset(dfn,0,sizeof(dfn));26 memset(in,0,sizeof(in));27 memset(out,0,sizeof(out));28 }29 30 void tarjan(int u){31 int i, j, v;32 dfn[u]=low[u]=dfn_clock++;33 st.push(u);34 for(i=0;i<ve[u].size();i++){35 v=ve[u][i];36 if(!dfn[v]){37 tarjan(v);38 low[u]=min(low[u],low[v]);39 }40 else if(instack[v]){41 low[u]=min(low[u],dfn[v]);42 }43 }44 if(low[u]==dfn[u]){45 cnt++;46 while(1){47 v=st.top();st.pop();48 a[v]=cnt;instack[v]=0;49 if(v==u) break;50 }51 }52 }53 54 main()55 {56 int i, j, k;57 int x, y;58 while(scanf("%d",&n)==1&&n){59 scanf("%d",&m);60 init();61 while(m--){62 scanf("%d %d",&x,&y);63 ve[x].push_back(y);64 }65 dfn_clock=1;cnt=0;66 for(i=1;i<=n;i++){67 if(!dfn[i])68 tarjan(i);69 }70 for(i=1;i<=n;i++){71 for(j=0;j<ve[i].size();j++){72 x=ve[i][j];73 if(a[x]!=a[i]){74 out[a[i]]++;in[a[x]]++;75 }76 }77 }78 k=0;79 for(i=1;i<=n;i++){80 if(!out[a[i]]){81 b[k++]=i;82 }83 }84 sort(b,b+k);85 printf("%d",b[0]);86 for(i=1;i<k;i++) printf(" %d",b[i]);87 cout<<endl;88 }89 }
Poj 2553 taarjan contraction point + degree