SSummerZzz kuangbin专题 专题九 连通图 Network UVA – 315

题目链接:https://vjudge.net/problem/POJ-1236

题目:有向图,有若干个连通图,点之间有单向边边就可以单向传递信息,问:

(1)至少需要发送几份信息才能使得每个点都传递到信息

(2)至少需要加几条边,才能使得“把一份信息发送到任意某个点就能传播到其他所有点”成立

 

思路:tarjan求强连通分量,强联通分量可以相互传递消息,然后,按强联通编号重构图,

统计每个强联通分量的入度出度情况。第一个答案,就显然是入度为0的点,第二个就是max(p,q),构成一个强联通图

这里给情况来解释下max    (1)1->2   3->2     (2) 1->2   1->3

p = 入度为0的强联通分量数

q = 出为为0的强联通分量数

 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 }

相关文章