题: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
