SSummerZzz kuangbin專題 專題九 連通圖 Network UVA - 315

題目連接:https://vjudge.net/problem/POJ-1236node

題目:有向圖,有若干個連通圖,點之間有單向邊邊就能夠單向傳遞信息,問:ios

(1)至少須要發送幾份信息才能使得每一個點都傳遞到信息ui

(2)至少須要加幾條邊,才能使得「把一份信息發送到任意某個點就能傳播到其餘全部點」成立spa

 

思路:tarjan求強連通份量,強聯通份量能夠相互傳遞消息,而後,按強聯通編號重構圖,.net

統計每一個強聯通份量的入度出度狀況。第一個答案,就顯然是入度爲0的點,第二個就是max(p,q),構成一個強聯通圖code

這裏給狀況來解釋下max    (1)1->2   3->2     (2) 1->2   1->3blog

p = 入度爲0的強聯通份量數get

q = 出爲爲0的強聯通份量數it

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int N = 110;
 7 int head[N],dfn[N],low[N],scc_no[N],s[N],ins[N],ru[N],chu[N];
 8 int n,scc,tim,tot,top;
 9 struct node{
10     int to;
11     int nxt;
12 }e[N*N];
13 
14 inline void add(int u,int v){
15     e[tot].to = v;
16     e[tot].nxt = head[u];
17     head[u] = tot++;
18 }
19 
20 void tarjan(int now,int pre){
21     dfn[now] = low[now] = ++tim;
22     ins[now] = 1;
23     s[top++] = now;
24 
25     int to;
26     for(int o = head[now]; ~o; o = e[o].nxt){
27         to = e[o].to;
28         if(!dfn[to]){
29             tarjan(to,now);
30             low[now] = min(low[now],low[to]);
31         }
32         else if(ins[to] && low[now] > dfn[to]) low[now] = dfn[to];
33     }
34 
35     if(dfn[now] == low[now]){
36         int x;
37         ++scc;
38         do{
39             x= s[--top];
40             ins[x] = 0;
41             scc_no[x] = scc;
42         }while(now != x);
43     }
44 }
45 
46 //重構圖,統計入度出度狀況
47 void rebuild(){
48     int to;
49     for(int now = 1; now <= n; ++now){
50         for(int o = head[now]; ~o; o = e[o].nxt){
51            to = e[o].to;
52            if(scc_no[to] != scc_no[now]){
53                 ++ru[scc_no[to]];
54                 ++chu[scc_no[now]];
55            }
56         }
57     }
58 }
59 
60 int main(){
61 
62     scanf("%d",&n);
63     for(int i = 0; i <= n; ++i) head[i] = -1;
64     int v;
65     for(int u = 1; u <= n; ++u){
66         while(~scanf("%d",&v) && v){
67             add(u,v);
68         }
69     }
70     for(int i = 1; i <= n; ++i){
71         if(!dfn[i])
72             tarjan(i,i);
73     }
74     rebuild();
75     int p = 0,q = 0;
76     for(int i = 1; i <= scc; ++i){
77         if(!ru[i]) ++p;
78         if(!chu[i]) ++q;
79     }
80     if(scc == 1) printf("1\n0\n");
81     else printf("%d\n%d\n",p,max(p,q));
82 
83 
84     return 0;
85 }
相關文章
相關標籤/搜索