标签:second limit 问题解决 info format memory dev this agreement
Description
Input
Output
Sample Input
5 2 4 3 0 4 5 0 0 0 1 0
Sample Output
12
这个题最大的难点在于任务二。任务二的意思就是加入最少的边使一个有向图变成强连通图,有一个定理是max(n,m)当中n是出度为0的点的个数,m是入度为0的点的个数,当然,假设这个图是强连通图的话。就须要讨论了,这时答案就是0了。将第二个问题解决掉。这个题就是一个模板题了,可是我如今仍没有证明这个命题的正确性!有大神说显然。我认为应该能够证出来。希望看到这个博客的大神能够帮帮忙。谢谢。
#include<stdio.h> #include<stack> #include<string.h> #include<algorithm> using namespace std; int dfn[120]; int belong[120],bnt,instack[120]; int index,out[120],in[120],low[120]; int map[120][120]; stack<int>S; void tarjan(int i){ dfn[i] = low[i] = ++index; S.push(i); instack[i] = 1; for(int j = 1;j<=map[i][0];j++){ int k = map[i][j]; if(!dfn[k]){ tarjan(k); low[i] = min(low[i],low[k]); } else if(instack[k]) low[i] = min(low[i],dfn[k]); } if(low[i] == dfn[i]){ bnt++; int j; do{ j = S.top(); S.pop(); instack[j] = 0; belong[j] = bnt; }while(i!=j); } } int main(){ int n,m,ans,ans1; while(~scanf("%d",&n)){ memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(instack,0,sizeof(instack)); memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); memset(map,0,sizeof(map)); bnt = index = 0; ans = ans1 = 0; for(int i=1;i<=n;i++){ while(scanf("%d",&m),m) if(m)map[i][++map[i][0]] = m; } for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i); for(int i=1;i<=n;i++){ for(int j = 1;j<=map[i][0];j++){ if(belong[i]!=belong[map[i][j]]){ out[belong[i]]++; in[belong[map[i][j]]]++; } } } for(int i=1;i<=bnt;i++){ if(out[i]==0)ans++; if(in[i]==0)ans1++; } printf("%d\n",ans1); if(bnt ==1)printf("0\n"); else printf("%d\n",max(ans1,ans)); } }
标签:second limit 问题解决 info format memory dev this agreement
原文地址:http://www.cnblogs.com/brucemengbm/p/6727212.html