您的位置:首页 > 其它

Strongly connected-HDU4635

2015-11-03 18:05 113 查看
Problem - 4635 http://acm.hdu.edu.cn/showproblem.php?pid=4635
题目大意:

n个点,m条边,求最多再加几条边,然后这个图不是强连通

分析:

这是一个单向图,如果强连通的话,他最多应该有n*(n-1)条边,假设有a个强连通块,任取其中一个强连通块,假设取出的这个强连通块里有x个点,剩下的(n-a)个点看成一个强连通块,如果让这两个强连通块之间不联通,肯定是这两个只有一个方向的边,最多就会有x*(n-x)条边 所以最多加n*(n-1)-x*x(n-x)-m边。所以当x最小是式子最大。

[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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>

using namespace std;
#define N 100005
#define INF 0x3f3f3f3f

struct node
{
int to,next;
}edge[N*10];

int low
,dfn
,Time,top,ans,Stack
,belong
,sum,head
,aa
,in
,out
,Is
;

void Inn()
{
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(Stack,0,sizeof(Stack));
memset(belong,0,sizeof(belong));
memset(head,-1,sizeof(head));
memset(aa,0,sizeof(aa));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(Is,0,sizeof(Is));
Time=top=ans=sum=0;
}

void add(int from,int to)
{
edge[ans].to=to;
edge[ans].next=head[from];
head[from]=ans++;
}

void Tarjin(int u,int f)
{
low[u]=dfn[u]=++Time;
Stack[top++]=u;
Is[u]=1;
int v;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if(!dfn[v])
{
Tarjin(v,u);
low[u]=min(low[u],low[v]);
}
else if(Is[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
sum++;
do
{
v=Stack[--top];
belong[v]=sum;
aa[sum]++;
Is[v]=0;
}while(v!=u);
}
}

void solve(int n,int m)
{
for(int i=1;i<=n;i++)
{
if(!dfn[i])
Tarjin(i,0);
}
if(sum==1)
{
printf("-1\n");
return ;
}
long long Max=0;
for(int i=1;i<=n;i++)
{
for(int j=head[i];j!=-1;j=edge[j].next)
{
int u=belong[i];
int v=belong[edge[j].to];
if(u!=v)
{
in[v]++;
out[u]++;
}
}
}
long long c=n*(n-1)-m;
for(int i=1;i<=sum;i++)
{
if(!in[i] || !out[i])
Max=max(Max,c-(aa[i]*(n-aa[i])));
}
printf("%lld\n",Max);
}
int main()
{
int T,n,m,a,b,i,t=1;
scanf("%d",&T);
while(T--)
{
Inn();
scanf("%d %d",&n,&m);
for(i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
add(a,b);
}
printf("Case %d: ",t++);
solve(n,m);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: