HDU4625:Strongly connected(思维+强连通分量)
Strongly connected
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4765 Accepted Submission(s): 1880
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635
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
题意:
给出一个有向图,保证图中无重边。现在要求加尽量多的边,使得最终的图不是强连通的,即任意两点可以互相到达,并且图中无重边。
题解:
可以想到,最终的图是一个二部图,设左边这部分为X,右边这部分为Y,那么X,Y之间只有单向边,同时X,Y中所有点都是强连通的,此时满足条件。
现在的问题就是这么确定这个X,Y。假设X中有x个点,同理,Y中有y个点,然后来计算一波:
此时图中的边数为x*(x-1)+y*(y-1)+x*y=x2+y2+x*y-x-y=(x+y)2-x*y-x-y=n2-n-x*y。现在要使得边数最大,那么x*y就尽量小,又因为x+y为定值,那么要么x尽可能小,要么y尽可能小就是了。
然后由于图中可能存在环,我们就先用Tarjan缩点,然后选取包含点数最少,并且出度或者入度为0的那个点作为X部,之后计算一波就行了。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1e5+;
int t,n,m,tot;
int head[N],num[N],in[N],out[N];
stack <int> s;
struct Edge{
int u,v,next;
}e[N<<],g[N<<];
void adde(int u,int v){
e[tot].u=u;e[tot].v=v;e[tot].next=head[u];head[u]=tot++;
}
int T,cc;
int scc[N],dfn[N],low[N],vis[N];
void Tarjan(int u){
dfn[u]=low[u]=++T;vis[u]=;
s.push(u);
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!vis[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(!scc[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
cc++;int now;
do{
now = s.top();s.pop();
scc[now]=cc;
num[cc]++;
}while(!s.empty() && now!=u);
}
}
int main(){
cin>>t;
int Case=;
while(t--){
Case++;
memset(head,-,sizeof(head));tot=;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
g[i].u=u;g[i].v=v;
adde(u,v);
}
memset(dfn,,sizeof(dfn));
memset(scc,,sizeof(scc));T=;
memset(vis,,sizeof(vis));cc=;
memset(num,,sizeof(num));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
for(int i=;i<=n;i++){
if(!vis[i]) Tarjan(i);
}
printf("Case %d: ",Case);
if(cc==){
puts("-1");
continue ;
}
for(int i=;i<=m;i++){
int u=g[i].u,v=g[i].v;
if(scc[u]==scc[v]) continue ;
in[scc[v]]++;out[scc[u]]++;
}
ll tmp = n*(n-)-m;
ll ans = ;
for(int i=;i<=cc;i++){
if(!in[i] || !out[i]) ans=max(ans,tmp-num[i]*(n-num[i]));
}
cout<<ans<<endl;
}
return ;
}
HDU4625:Strongly connected(思维+强连通分量)的更多相关文章
- [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.思路:把图分成 ...
- Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )
题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...
- hdu 4635 Strongly connected(强连通)
考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...
- HDU4635 Strongly connected【强连通】
题意: 给一个n个点的简单有向图,问最多能加多少条边使得该图仍然是简单有向图,且不是强连通图.简单有向图的定义为:没有重边,无自环. 强连通图的定义为:整个图缩点后就只有一个点,里面包含n个原点,也就 ...
随机推荐
- python 终极篇 --- form组件 与 modelForm
form组件 ...
- 【第四章】MySQL数据库的基本操作:数据库、表的创建插入查看
MySQL数据库基本操作 创建表 create table 查看表结构 desc table, show create table 表完整性约束 修改表 alter table 复制表 create ...
- 【第六章】MySQL日志文件管理
1.日志文件管理概述: 配置文件:/etc/my.cnf 作用:MySQL日志文件是用来记录MySQL数据库客户端连接情况.SQL语句的执行情况以及错误信息告示. 分类:MySQL日志文件分为4种:错 ...
- [2018 ACL Short and System] 对话系统
Short Paper(s) 1. Task-oriented Dialogue System for Automatic Diagnosis. (Cited by 0) Zhongyu Wei, ...
- halcon安装提示could not write updated path to HKLM
halcon安装提示could not write updated path to HKLM 我们在安装Halcon软件时,会弹出如上图错误信息,这个错误信息提示软件无法写入本地注册表,造成这个原因有 ...
- Ext JS 6学习文档-第8章-主题和响应式设计
Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...
- POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)
Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...
- 动态内存&对象
一.对象的生存期 对于 static 对象和自动对象,它们都有着严格定义的生存期. 全局对象:在程序启动时分配,在程序结束时销毁. 局部自动对象:在对象定义语句时分配,在离开块时销毁 局部 stati ...
- Alpha阶段中间产物——Thunder团队
Part One 版本控制 git地址:https://git.coding.net/lick468/iReader.git Part Two 软件功能说明书 相关链接:http://www.cnbl ...
- Python学习之路5 - 函数
函数 定义方式: def func(): "这里面写函数的描述" 这里写代码 return x #如果没有返回值就叫"过程",函数和过程的区别就是有无返回值 实 ...