POJ 1236 Network of Schools(tarjan求強連通分量+思維)
阿新 • • 發佈:2018-03-24
一個 div http mes pos 全部 tde bre 一點
題目鏈接:http://poj.org/problem?id=1236
題目大意:
給你一個網絡(有向圖),有兩個任務:
①求出至少同時需要幾份副本可以使得整個網絡都獲得副本
②至少添加多少信息表(有向邊)使得副本傳到任一點,都可以使得整個網絡都獲得副本
解題思路:
即給定一個有向圖,求:
①至少要選幾個頂點,才能做到從這些頂點出發,可以到達全部頂點
②至少要加多少條邊,才能使得從任何一個頂點出發,都能到達全部頂點
縮點後,分別求出出度入度為0的點數為sum1,sum2,
問題①的答案就為sum2;
問題②的答案為max(sum1,sum2)(即使得所有點的出度入度都大於0)。
註意,只有一個點時,不需要添加邊,答案為1,0。
代碼
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stack> 6 #include<vector> 7 using namespace std; 8 const int N=105; 9 10 int n,cnt,num; //cnt為當前dfs序,num為縮點編號 11 int low[N],dfn[N],fa[N],indeg[N],outdeg[N];//dfn為dfs序,low為節點能夠通過返回的最早的祖先(註意這裏跟求割邊割點裏的low不同) 12 vector<int>v[N]; //fa為節點所屬的強聯通分量的編號.indeg和outdeg為縮點的入度、出度 13 stack<int>sk; 14 15 void init(){ 16 cnt=num=0; 17 for(int i=1;i<=n;i++){ 18 v[i].clear(); 19 } 20 memset(fa,0,sizeof(fa));21 memset(low,0,sizeof(low)); 22 memset(dfn,0,sizeof(dfn)); 23 memset(indeg,0,sizeof(indeg)); 24 memset(outdeg,0,sizeof(outdeg)); 25 } 26 27 //求強聯通分量 28 void tarjan(int u){ 29 low[u]=dfn[u]=++cnt; 30 sk.push(u); 31 for(int i=0;i<v[u].size();i++){ 32 int t=v[u][i]; 33 if(!dfn[t]){ //未被訪問 34 tarjan(t); 35 low[u]=min(low[u],low[t]); 36 } 37 else if(!fa[t]) low[u]=min(low[u],dfn[t]); //被訪問過且在棧中 38 } 39 if(low[u]==dfn[u]){ 40 num++; 41 while(!sk.empty()){ 42 int t=sk.top(); 43 sk.pop(); 44 fa[t]=num; 45 if(t==u) break; 46 } 47 } 48 } 49 50 int main(){ 51 while(~scanf("%d",&n)){ 52 init(); 53 for(int i=1;i<=n;i++){ 54 int x; 55 while(~scanf("%d",&x)&&x) v[i].push_back(x); 56 } 57 for(int i=1;i<=n;i++){ //遍歷所有點 58 if(!dfn[i]) tarjan(i); 59 } 60 for(int i=1;i<=n;i++){ //縮點,並求出相應的出度入度是否為0(註意不是求出入度) 61 for(int j=0;j<v[i].size();j++){ 62 int t=v[i][j]; 63 if(fa[t]!=fa[i]){ 64 outdeg[fa[i]]=1; 65 indeg[fa[t]]=1; 66 } 67 } 68 } 69 int sum1=0,sum2=0; 70 for(int i=1;i<=num;i++){ 71 if(outdeg[i]==0) 72 sum1++; 73 if(indeg[i]==0) 74 sum2++; 75 } 76 if(num==1) //只有一個點時要特判 77 puts("1\n0"); 78 else printf("%d\n%d\n",sum2,max(sum1,sum2)); 79 } 80 return 0; 81 }
POJ 1236 Network of Schools(tarjan求強連通分量+思維)