POJ 1236 Network of Schools )
subject
The topic is very long. In fact, the meaning of the topic is very simple. Give a digraph and ask
- You can walk through the whole picture from at least a few points
- Adding at least a few edges can make the graph strongly connected
Analysis
Direct Tarjian Tarjian Tarjian reduction point after analysis of the nature of DAGDAGDAG graph, from all starting points can walk through the whole graph, it seems that the degree of zero point. The second problem is the degree of entry of the built DAGDAGDAG graph, and the number of nodes with a degree of 0 is a, B. Ensure that the edges of max(a,b)max(a,b)max(a,b) are added.
Find out the entrance and exit table of SCCSCCSCC chart. First, assume that each point is not connected, that is, the initial entry is 0, when u points to the edge of v, the entry of v, the exit of u is 1.
The strong connected graph is specially judged later. /
Code
#include<cstdio> #include <iostream> #include<algorithm> #include<vector> #include<cstring> #include<stack> using namespace std; #define d(x) cout<<(x)<<endl const int N = 1e3 + 10; int n; int pre[N], sccno[N], scc_cnt, low[N], dfs_clock; vector<int> e[N]; stack<int> s; void dfs(int u){ pre[u] = low[u] = ++dfs_clock; s.push(u); for(int i = 0; i < e[u].size(); i++){ int v = e[u][i]; if(!pre[v]){ dfs(v); low[u] = min(low[u], low[v]); }else if(!sccno[v]){ low[u] = min(low[u], pre[v]); } } if(low[u] == pre[u]){ scc_cnt++; while(1){ int x = s.top(); s.pop(); sccno[x] = scc_cnt; if(x == u) break; } } } void find_scc(){ memset(pre, 0, sizeof(pre)); memset(sccno, 0, sizeof(sccno)); dfs_clock = scc_cnt = 0; for(int i = 1; i <= n; i++){ if (!pre[i]){ dfs(i); } } } void cal(){ int in[N], out[N]; for(int i = 1; i <= scc_cnt; i++) in[i] = out[i] = 1; for(int u = 1; u <= n; u++){ for(int i = 0; i < e[u].size(); i++){ int v = e[u][i]; if(sccno[u] != sccno[v]) in[sccno[v]] = out[sccno[u]] = 0; } } int a = 0, b = 0; for(int i = 1; i <= scc_cnt; i++){ if(in[i]) a++; if(out[i]) b++; } printf("%d\n%d\n", a, max(a, b)); } int main(){ scanf("%d", &n); for(int i = 1, x; i <= n; i++){ while(scanf("%d", &x) && x){ e[i].push_back(x); } } find_scc(); // d("fd"); if(scc_cnt == 1){ printf("1\n0\n"); }else{ cal(); } return 0; }