题:http://acm.hdu.edu.cn/showproblem.php?pid=4635
题意:给n个点m条边的有向图,问最多还能添加多少条边,让此图还不能形成强连通图;
分析:tarjan缩点后,我们知道要是点双的个数是1那么肯定不符合条件,就直接输出-1;
那么剩下的情况就是,我们挑出一个点双,让剩余的点双全连通起来,当前点的点双也全连通起来,就剩下俩个点双,俩个点双之间也要尽可能连边;
我们假设当前点双为 i ,剩下的点双 为 j (已经全连通过了),那么要是一开始 j 中的俩个点双分为对 i 有入边和出边,那么 i 和 j 就肯定能连通,就不满足条件了,所以我们要挑那些要么入度为0要么出度为0要么度数为0的点点双来考虑;
对于每一个点双,答案贡献有三部分:1、当前点双 i 还能添加多少条边达到全连通;
2、剩下点双 j 还能添加多少条边达到全连通;
3、i 和 j 之间还能添加多少条边让i 和 j 不连通(i 和 j 之间的边要么全是出边要么全是入边)
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int M=1e5+5; vector<int>g[M]; int dfn[M],low[M],sta[M],cmp[M],in[M],out[M],n,m,top,tot,cnt; bool vis[M]; ll sum[M],du[M],line[M]; void tarjan(int u){ dfn[u]=low[u]=++cnt; sta[++top]=u; vis[u]=true; for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(!dfn[v]){ tarjan(v),low[u]=min(low[u],low[v]); } else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ cmp[u]=++tot; vis[u]=false; int len=top; while(sta[top]!=u){ cmp[sta[top]]=tot; vis[sta[top--]]=false; } top--; sum[tot]=len-top; } } void init(){ tot=top=cnt=0; for(int i=0;i<=n;i++) g[i].clear(),cmp[i]=0,low[i]=0,dfn[i]=0,out[i]=0,in[i]=0,line[i]=0,du[i]=0,sum[i]=0; } int main(){ int t; scanf("%d",&t); for(int p=1;p<=t;p++){ scanf("%d%d",&n,&m); init(); for(int u,v,i=1;i<=m;i++){ scanf("%d%d",&u,&v); g[u].pb(v); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); printf("Case %d: ",p); if(tot==1){ puts("-1"); continue; } ll ans=0; for(int i=1;i<=n;i++) for(int j=0;j<g[i].size();j++){ int v=g[i][j]; if(cmp[i]!=cmp[v]){ out[cmp[i]]++; in[cmp[v]]++; du[cmp[i]]++; du[cmp[v]]++; } else line[cmp[i]]++; } for(int i=1;i<=tot;i++){ ll nownum=1ll*(n-sum[i]); ll sum1=nownum*(nownum-1);///外面的连通块的总边数; ll sum2=1ll*(m-line[i]-du[i]);///外面的连通块已经连的边数; ll sum3=sum[i]*nownum-du[i];///当前点可以再和外面连多少边; ll sum4=sum[i]*(sum[i]-1)-line[i];///当前连通块里还可以连的边 // cout<<sum1-sum2<<"@@"<<sum3<<"@@"<<sum4<<endl; if(!du[i]||!in[i]||!out[i]){ ans=max(ans,(sum1-sum2)+sum3+sum4); // ans=max(ans,sum1-(m-line[i]-du[i])+sum[i]*nownum-du[i]); } } printf("%lld\n",ans); } return 0; }
来源:https://www.cnblogs.com/starve/p/12427730.html