您的位置:首页 > 其它

HDU 4635 Strongly connected ( 强连通分量 )

2018-03-20 18:27 357 查看

Strongly connected

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3735    Accepted Submission(s): 1481

[align=left]Problem Description[/align]Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a simple directed graph. Also, after you add these edges, this graph must NOT be strongly connected.
A simple directed graph is a directed graph having no multiple edges or graph loops.
A strongly connected digraph is a directed graph in which it is possible to reach any node starting from any other node by traversing edges in the direction(s) in which they point.
 
[align=left]Input[/align]The first line of date is an integer T, which is the number of the text cases.
Then T cases follow, each case starts of two numbers N and M, 1<=N<=100000, 1<=M<=100000, representing the number of nodes and the number of edges, then M lines follow. Each line contains two integers x and y, means that there is a edge from x to y. 
[align=left]Output[/align]For each case, you should output the maximum number of the edges you can add.
If the original graph is strongly connected, just output -1. 
[align=left]Sample Input[/align]
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 
[align=left]Sample Output[/align]
Case 1: -1
Case 2: 1
Case 3: 15 
[align=left]Source[/align]2013 Multi-University Training Contest 4  
[align=left]Recommend[/align]zhuyuanchen520
题意:一个有向图,问最多能添加多少条边使这个图仍不强连通
可假设最后所求的图由两个强连通图(图U和图V)组成,且图U和图V之前只有单向边,此时既满足整个图不强连通,又能保证有最多的边。
设图U的顶点数为x,图V的顶点数为y  ( x+y=n )
图U强连通,边数最多为 x*(x-1)

图V强连通,边数最多为 y*(y-1)

图U和图V之前只有单向边,则边数最多为 x*y

图的总边数 sum = x*y+x*(x-1)+y*(y-1) = n*n-n-x*y
即可转化为求 x*y 的最小值,即求顶点数最小的强连通分量
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#define maxn 100010
using namespace std;
int n,m,q,cnt,sum,index;
int dfn[maxn],low[maxn],belong[maxn],instack[maxn];
int in[maxn],out[maxn],num[maxn];
stack<int>s;
vector<int>g[maxn];
struct li
{
int a,b;
}link[maxn];
void tarjan(int x)
{
int i,j;
low[x]=dfn[x]=++index;
s.push(x);
instack[x]=1;
for(i=0;i<g[x].size();i++)
{
int k=g[x][i];
if(!dfn[k])
{
tarjan(k);
low[x]=min(low[x],low[k]);
}
else if(instack[k])
low[x]=min(low[x],dfn[k]);
}
if(dfn[x]==low[x])
{
sum++;
while(!s.empty())
{
j=s.top();
s.pop();
instack[j]=0;
num[sum]++;
belong[j]=sum;
if(j==x)
break;
}
}
}
int main ()
{
int i,j,a,b,t,cas=1;
scanf("%d",&t);
while(t--)
{
while(!s.empty())
s.pop();
memset(belong,0,sizeof(belong));
memset(instack,0,sizeof(instack));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(g,0,sizeof(g));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(num,0,sizeof(num));
index=sum=0;
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d %d",&a,&b);
link[i].a=a;
link[i].b=b;
g[a].push_back(b);
}
for(i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(i=1;i<=m;i++)
{
if(belong[link[i].a]!=belong[link[i].b])
{
out[belong[link[i].
8fcf
a]]++;
in[belong[link[i].b]]++;
}
}
long long ans=-1;
for(i=1;i<=sum;i++)
{
if(in[i]==0||out[i]==0)
{
long long k=num[i];
ans=max(ans,k*(n-k)+k*(k-1)+(n-k)*(n-k-1)-m);
}
}
printf("Case %d: ",cas++);
if(sum<=1)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: