1. 程式人生 > >POJ 1236 Network of Schools

POJ 1236 Network of Schools

mes rip 不能 algorithm 強連通分量 deep oid map n)

Description

一些學校連入一個電腦網絡。那些學校已訂立了協議:每個學校都會給其它的一些學校分發軟件(稱作“接受學校”)。註意如果 B 在 A 學校的分發列表中,那麽 A 不必也在 B 學校的列表中。
你要寫一個程序計算,根據協議,為了讓網絡中所有的學校都用上新軟件,必須接受新軟件副本的最少學校數目(子任務 A)。更進一步,我們想要確定通過給任意一個學校發送新軟件,這個軟件就會分發到網絡中的所有學校。為了完成這個任務,我們可能必須擴展接收學校列表,使其加入新成員。計算最少需要增加幾個擴展,使得不論我們給哪個學校發送新軟件,它都會到達其余所有的學校(子任務 B)。一個擴展就是在一個學校的接收學校列表中引入一個新成員。

Input

第一行包括一個整數 N:網絡中的學校數目(2 <= N <= 100)。學校用前 N 個正整數標識。
接下來 N 行中每行都表示一個接收學校列表(分發列表)。第 i+1 行包括學校 i 的接收學校的標識符。每個列表用 0 結束。空列表只用一個 0 表示。

Output

輸出兩行。第一行應該包括一個正整數:子任務 A 的解 。
第二行應該包括子任務 B 的解。

Sample Input

5
2 4 3 0
4 5 0
0
0
1 0

Sample Output

1
2

Hint

Source

USACO
強連通分量, 連通性

A 即為tarjan 縮點後的 DAG 上所有入度為 0 的點的數目。因為若點X入度為 0 ,則他不能從其他點處獲得軟件,所以必須給他一份軟件。

B 即為 添加多少條邊後,DAG 可變為一個環。感性的理解一下就是 max(入度為0的點,出度為0的點

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4
#include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define ll long long 16 #define file(a) freopen(a".in","r",stdin); freopen(a".out","w",stdout); 17 18 inline int gi() 19 { 20 bool b=0; int r=0; char c=getchar(); 21 while(c<0 || c>9) { if(c==-) b=!b; c=getchar(); } 22 while(c>=0 && c<=9) { r=r*10+c-0; c=getchar(); } 23 if(b) return -r; return r; 24 } 25 26 const int inf = 1e9+7, N = 107, M = 10007; 27 int n,num,f[N],dfn[N],low[N],bl[N],cnt,siz[N],Deep,cd[N],rd[N]; 28 bool b[N]; 29 struct data 30 { 31 int nx,fr,to; 32 }da[M]; 33 stack <int> s; 34 35 inline void add (int fr,int to) 36 { 37 da[++num].fr=fr, da[num].to=to, da[num].nx=f[fr], f[fr]=num; 38 } 39 40 inline void tarjan (int o) 41 { 42 dfn[o]=low[o]=++Deep; 43 s.push (o); b[o]=1; 44 int i,to; 45 for (i=f[o]; i; i=da[i].nx) 46 { 47 to=da[i].to; 48 if (!dfn[to]) tarjan (to), low[o]=min (low[o],low[to]); 49 else if(b[to]) low[o]=min (low[o],low[to]); 50 } 51 if (low[o] == dfn[o]) 52 { 53 cnt++; 54 do { to=s.top(), s.pop(), b[to]=0, bl[to]=cnt; } while (to != o); 55 } 56 } 57 58 int main() 59 { 60 // file("schlnet"); 61 n=gi(); 62 int i,x,y; 63 for (i=1; i<=n; i++) 64 { 65 x=gi(); 66 while (x) add (i,x), x=gi(); 67 } 68 for (i=1; i<=n; i++) if (!dfn[i]) tarjan (i); 69 if (cnt == 1) { puts ("1\n0"); return 0; } 70 for (i=1; i<=num; i++) 71 { 72 x=bl[da[i].fr], y=bl[da[i].to]; 73 if (x != y) cd[x]++, rd[y]++; 74 } 75 x=0, y=0; 76 for (i=1; i<=cnt; i++) 77 { 78 if (!rd[i]) x++; 79 if (!cd[i]) y++; 80 } 81 printf("%d\n%d\n",x,max (x,y)); 82 return 0; 83 }

POJ 1236 Network of Schools