3 3 3 1 2 2 3 3 1 3 3 1 2 2 3 1 3 6 6 1 2 2 3 3 1 4 5 5 6 6 4
Case 1: -1 Case 2: 1 Case 3: 15
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define ll __int64 const int N = 100005; struct EDG{ int to,next; }edg[N]; int eid,head[N]; int low[N],dfn[N],vist[N],num[N],id[N],deep,stack1[N],tn,top; int in[N],out[N]; void init(){ eid=tn=top=deep=0; memset(head,-1,sizeof(head)); memset(vist,0,sizeof(vist)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(num,0,sizeof(num)); } void addEdg(int u,int v){ edg[eid].to=v; edg[eid].next=head[u]; head[u]=eid++; } void tarjer(int u){ stack1[++top]=u; vist[u]=1; deep++; low[u]=dfn[u]=deep; for(int i=head[u]; i!=-1; i=edg[i].next){ int v=edg[i].to; if(vist[v]==0){ vist[v]=1; tarjer(v); low[u]=min(low[u],low[v]); } else if(vist[v]==1) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]){ tn++; do{ vist[stack1[top]]=2; num[tn]++; id[stack1[top]]=tn; }while(stack1[top--]!=u); } } ll solve(int n,int m){ ll ans=n*(n-1)-m; int minnum=N; for(int i=1; i<=n; i++) if(vist[i]==0) tarjer(i); if(tn==1) return -1; for(int u=1; u<=n; u++) for(int i=head[u]; i!=-1; i=edg[i].next){ int v=edg[i].to; if(id[u]!=id[v]) in[id[v]]++,out[id[u]]++; } for(int i=1; i<=tn; i++) if(in[i]==0||out[i]==0){ minnum=min(minnum,num[i]); } ans-=minnum*(n-minnum); return ans; } int main(){ int T,n,m,c=0,a,b; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); init(); for(int i=1; i<=m; i++) { scanf("%d%d",&a,&b); addEdg(a,b); } printf("Case %d: %I64d\n",++c,solve(n,m)); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 4635 Strongly connected(强连通)经典
原文地址:http://blog.csdn.net/u010372095/article/details/46888807