标签:nes bottom head however ace osi lin using clear
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7346 Accepted Submission(s): 2539
那么要加边的条数就是max(cntOut,cntIn)
这个为什么呢?? 因为,如果一个点的入度为0,那么说明这个点是不可达的,如果一个点的出度为0,那么说明这个点到其它点是不可达的。
为了解决这个情况,那么只要在出度为0的点(设为u)和入度为0的点之间连一条u-->v的边,那么就解决了这种情况。
不断的连边,只要一个点问题没解决就要连边, 所以是在两者之间取max 此段论述http://www.cnblogs.com/justPassBy/p/4678192.html转自这里
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=20008; const int M=50008; int head[N],bl[N],q[N],dfn[N],low[N]; int tot,scnt,cnt,l,n,m; bool instack[N],ru[N],out[N]; struct node{ int to,next; }e[M]; void init(){ for(int i=0;i<=n;++i) { head[i]=-1; dfn[i]=instack[i]=0; ru[i]=out[i]=0; } l=tot=scnt=cnt=0; } void add(int u,int v){ e[tot].to=v; e[tot].next=head[u]; head[u]=tot++; } void Tajan(int u){ dfn[u]=low[u]=++cnt; instack[u]=1; q[l++]=u; for(int i=head[u];i+1;i=e[i].next){ int v=e[i].to; if(!dfn[v]) { Tajan(v); low[u]=min(low[u],low[v]); } else if(instack[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } if(low[u]==dfn[u]){ int t; ++scnt; do{ t=q[--l]; instack[t]=0; bl[t]=scnt; }while(t!=u); } } int main(){ int u,v,T; for(scanf("%d",&T);T--;){ scanf("%d%d",&n,&m);init(); for(int i=1;i<=m;++i) { scanf("%d%d",&u,&v); add(u,v); } for(int i=1;i<=n;++i) if(!dfn[i]) Tajan(i); if(scnt==1) {puts("0");continue;} for(int i=1;i<=n;++i){ for(int j=head[i];j+1;j=e[j].next){ int v=e[j].to; if(bl[i]==bl[v]) continue; else { ru[bl[v]]=1; out[bl[i]]=1; } } } int ans1=0,ans2=0; for(int i=1;i<=scnt;++i){ if(!out[i]) ++ans1; if(!ru[i]) ++ans2; } printf("%d\n",max(ans1,ans2)); } }
标签:nes bottom head however ace osi lin using clear
原文地址:http://www.cnblogs.com/mfys/p/7258929.html