Strongly connected(hdu4635(强连通分量))
/*
http://acm.hdu.edu.cn/showproblem.php?pid=4635
Strongly connected
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 477 Accepted Submission(s): 212
Problem Description
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.
Input
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.
Output
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.
Sample Input
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
Sample Output
Case 1: -1
Case 2: 1
Case 3: 15
Source
2013 Multi-University Training Contest 4
Recommend
zhuyuanchen520
解析:
题意:
解析:给出一个有向图,问最多可以加多少边使得任意两点无论正反方向皆可到达
思路:最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数尽可能的多,则X部肯定是一个完全图,Y部也是,同时X部中每个点到Y部的每个点都有一条边,假设X部有x个点,Y部有y个点,有x+y=n,同时边数F=x*y+x*(x-1)+y*(y-1),整理得:F=N*N-N-x*y,当x+y为定值时,二者越接近,x*y越大,所以要使得边数最多,那么X部和Y部的点数的个数差距就要越大,所以首先对于给定的有向图缩点,对于缩点后的每个点,如果它的出度或者入度为0,那么它才有可能成为X部或者Y部,所以只要求缩点之后的出度或者入度为0的点中,包含节点数最少的那个点,令它为一个部,其它所有点加起来做另一个部,就可以得到最多边数的图了
故:1要用tarjan算法进行缩点
2.缩点后重建图
3.找出出度或入度为0且结点最小点,套用公式
46MS 5436K 2350 B C++
*/
#pragma comment(linker, "/STACK:1024000000,1024000000")/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=100000+10;
int pre[maxn],scc[maxn],low[maxn],st[maxn];
int nodenum[maxn],head1[maxn],head2[maxn],vis[maxn];
int dfsn,sccn,top,ans,t1,t2,m,n;
struct Edge
{
int s;
int t;
int next;
}edge[maxn];
struct Node
{
int fn;//出度
int tn;//入度
int num;//缩点后每个“结点”含有的节点数
}node[maxn];
int min(int a,int b)
{
return a<b? a:b;
}
void init()
{
memset(pre,0,sizeof(pre));
memset(scc,0,sizeof(scc));
memset(low,0,sizeof(low));
memset(st,0,sizeof(st));
memset(vis,0,sizeof(vis));
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
dfsn=sccn=top=ans=t1=t2=0;
}
void add1(int s,int t)
{
edge[t1].s=s;
edge[t1].t=t;
edge[t1].next=head1[s];
head1[s]=t1++;
}
void add2(int s,int t)
{
edge[t2].s=s;
edge[t2].t=t;
edge[t2].next=head2[s];
head2[s]=t2++;
}
void dfs(int u)//缩点
{
pre[u]=low[u]=++dfsn;
st[top++]=u;
vis[u]=1;//标记已访问的点
for(int i=head1[u];i!=-1;i=edge[i].next)
{
int v=edge[i].t;
if(!pre[v])
{
dfs(v);
low[u]=min(low[u],low[v]);
}
else if(!scc[v])
low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u])
{
int k=0;
sccn++;
for(;;)
{
int x=st[--top];
scc[x]=sccn;
k++;
if(x==u)
break;
}
node[sccn].num=k;//记录缩点后的信息
node[sccn].fn=0;
node[sccn].tn=0;
}
}
void work()
{
for(int i=1;i<=n;i++)//这样做的目的是保证每个结点都可以访问到
{
if(!vis[i])
dfs(i); }
//printf("sccn==%d\n",sccn);
if(sccn==1)//如果当且仅当只有用一个强连通分量时,不需要加边
{
ans=-1;
return;
} for(int i=0;i<t1;i++)//缩点后重建图。并记录每个结点的出度和入度数
{
int u=scc[edge[i].s];
int v=scc[edge[i].t];
add2(u,v);
if(u!=v)
{
node[u].tn++;
node[v].fn++;
}
}
int Min=100000000,sum=0;
for(int i=1;i<=sccn;i++)
{
if(node[i].fn==0||node[i].tn==0)//取出度或入读为0的点
{if(Min>node[i].num)
Min=node[i].num;
}
sum+=node[i].num;
}
ans=sum*sum-sum-Min*(sum-Min)-m;
}
int main()
{
int T,i,j,u,v;
int c=0;
scanf("%d",&T);
while(T--)
{ init();
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
add1(u,v);
}
work();
printf("Case %d: %d\n",++c,ans);
}
return 0;
}
Strongly connected(hdu4635(强连通分量))的更多相关文章
- [HDOJ4635]Strongly connected(强连通分量,缩点)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给一张图,问最多往这张图上加多少条边,使这张图仍然无法成为一个强连通图. 起初是先分析样例 ...
- HDU 4635 Strongly connected(强连通分量,变形)
题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...
- HDU 4635 Strongly connected ——(强连通分量)
好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...
- HDU 4635 Strongly connected(强连通分量缩点+数学思想)
题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...
- HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】
Strongly connected Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- HDU 4635:Strongly connected(强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给出n个点和m条边,问最多能添加几条边使得图不是一个强连通图.如果一开始强连通就-1.思路:把图分成 ...
- HDU4635 Strongly connected【强连通】
题意: 给一个n个点的简单有向图,问最多能加多少条边使得该图仍然是简单有向图,且不是强连通图.简单有向图的定义为:没有重边,无自环. 强连通图的定义为:整个图缩点后就只有一个点,里面包含n个原点,也就 ...
- hdu 4635 Strongly connected(强连通)
考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...
- POJ1236(KB9-A 强连通分量)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19326 Accepted: 75 ...
随机推荐
- NSIS:迅雷5.8.6.600自由定制版脚本及下载
原文 NSIS:迅雷5.8.6.600自由定制版脚本及下载 虽然现在迅雷已升级到7.2版本,但作为一款下载工具,我们可能只是需要它的下载功能,所以,体积小资源占用也小的迅雷5便成了我们更好的选择.今天 ...
- Doug Lea
如果IT的历史,是以人为主体串接起来的话,那么肯定少不了Doug Lea.这个鼻梁挂着眼镜,留着德王威廉二世的胡子,脸上永远挂着谦逊腼腆笑容,服务于纽约州立大学Oswego分校计算机科学系的老大爷. ...
- 本人第一个android游戏《新连连看》上架
经过艰苦奋战了几天,本人的第一个android游戏<新连连看>最终完毕了第一个版本号,比較简陋.另一部分功能保留没有开放.等第二个版本号再上.用的libgdx框架.可能不是非常出名,可是本 ...
- hdu1588---Gauss Fibonacci(矩阵,线性复发)
根据题意:最后一步是寻求f(b) + f(k + b) + f(2 * k + b) + -+ f((n-1) * k + b) 清除f(b) = A^b 间A = 1 1 1 0 所以sum(n - ...
- Entity Framework 6.1
Entity Framework 6.1-Code First Code First-代码优先,先创建好领域模型.根据... 2014-04-21 14:56 阅读(6858) 评论(0) Ent ...
- SQL2000 MD5加密
原文:SQL2000 MD5加密 /***************************************************************************** * Na ...
- HDU1051 Wooden Sticks 【贪婪】
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- ABP入门教程
ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- PostgreSQL 9.3 Streaming Replication 状态监控
postgresql是使用Streaming Replication来实现热备份的,热备份的作用如下: 灾难恢复 高可用性 负载均衡,当你使用Streaming Replication来实现热备份(h ...
- Com组件的内存分配和释放,CredentialProvider SHStrDup 字符串拷贝问题
一.简单介绍 熟悉CredentialProvider的同学应该知道,他为一个Com组件,于是,在这里的内存分配(字符串拷贝)的一系列操作就要依照con的标准来. 二.Com组件的内存分配和释放 CO ...