标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4635
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
/** hdu 4635 强连通分量+缩点 题目大意:给定一个图,问能最多加多少边使其还不是连通图 解题思路:http://www.xuebuyuan.com/1606580.html */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; typedef long long LL; const int maxn=100005; struct note { int v,next; }edge[maxn*10]; int head[maxn],ip; int st[maxn],ins[maxn],dfn[maxn],low[maxn],cnt_tar,index,top; int in[maxn],out[maxn],num[maxn],belong[maxn]; int m,n; void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } void init() { memset(head,-1,sizeof(head)); ip=0; } void tarjan(int u) { dfn[u]=low[u]=++index; st[++top]=u; ins[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(ins[v]) { low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]) { cnt_tar++; int j; do { j=st[top--]; ins[j]=0; belong[j]=cnt_tar; num[cnt_tar]++; }while(j!=u); } } void solve() { top=0,index=0,cnt_tar=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } } int main() { int T,tt=0; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); init(); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); } memset(num,0,sizeof(num)); solve(); if(cnt_tar==1) { printf("Case %d: -1\n",++tt); continue; } memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int u=1;u<=n;u++) { for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(belong[u]==belong[v])continue; out[belong[u]]++; in[belong[v]]++; } } LL all=(LL)n*(n-1)-m; LL ans=0; for(int i=1;i<=cnt_tar;i++) { if(in[i]==0||out[i]==0) { ans=max(ans,all-(LL)num[i]*(n-num[i])); } } printf("Case %d: %I64d\n",++tt,ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/43955231