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 ...
随机推荐
- HDU 1505 Largest Rectangle in a Histogram && HDU 1506 City Game(动态规划)
1506意甲冠军:给你一个连续的直方图(拼贴底部长度1).求连续基质区. 对每一个直方图,分别向左向右进行扩展. #include<cstdio> #include<stdlib.h ...
- JQuery插件开发初探——图片轮播
在熟悉了插件开发的结构以后,自己尝试着做了一个稍微复杂一点的小功能:图片轮播插件. 由于之前使用的一款图片轮播插件,性能不高,页面加载的时候需要载入全部的图片,因此速度很慢. 通过自己做这个小插件,能 ...
- PHP第三个教训 PHP基本数据类型
学习平台: 1.php七种变量类型 2.isset和empty到这两个功能区分 3.型式试验 4.自己主动类型转换 5.类型转换 注意: 1.通过 变量->方法名 来调用. $user1 = ...
- DevExpress.XtraReports.UI.XtraReport 动态报表
原文:DevExpress.XtraReports.UI.XtraReport 动态报表 using System;using System.Collections.Generic;using Sys ...
- 第7章 桥接模式(Bridge Pattern)
原文 第7章 桥接模式(Bridge Pattern) 定义: 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能 ...
- iOS开发必看的博客汇总
OneV's Den http://onevcat.com/ 沉船家园 http://beyondvincent.com/ NSHipster http://nshipster.cn/ Limboy ...
- css+html简单的布局demo
于html介绍css作风.可以改变html块状布局,局更加美观.接下来看一个基础布局的小样例: <html> <head> <meta http-equiv=" ...
- java_ java多线程返回函数结果
两种方式:一种继承Thread类实现:一种通过实现Callable接口. 第一种方法: 因为实现Thread类的run方法自身是没有返回值的,所以不能直接获得线程的执行结果,但是可以通过在run方法里 ...
- 从[java.lang.OutOfMemoryError: Java heap space]恢复
出现java.lang.OutOfMemoryError: Java heap space该错误或者是程序问题,或者被分配到JVM内存真的是不够的. 一般来说都是能够事前可控解决的. 可是假设不可控的 ...
- Ubuntu更改hosts档
Ubuntu更改hosts档 打开hosts档 sudo gedit /etc/hosts 下载hosts,并全选复制 hosts 粘贴到hosts文件里.保存就可以 $(function () { ...