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个原点,也就 ...
随机推荐
- Machine Learning分类:监督/无监督学习
从宏观方面,机器学习可以从不同角度来分类 是否在人类的干预/监督下训练.(supervised,unsupervised,semisupervised 以及 Reinforcement Learnin ...
- TensorFlow | ReluGrad input is not finite. Tensor had NaN values
问题的出现 Question 这个问题是我基于TensorFlow使用CNN训练MNIST数据集的时候遇到的.关键的相关代码是以下这部分: cross_entropy = -tf.reduce_sum ...
- 基础数据类型-list
序列是python中的基础数据结构,序列里每一个元素都有一个下标,从0开始,依次递增. list,tuple,dictionary是使用最频繁的三类数据结构. (1)序列都有的方法包括:索引,切片,检 ...
- sql分页使用join提高性能
今天在分析系统中的分页sql时意外知道了使用join可以提高分页性能. 逻辑是join部分使用单一表,单一字段排序分页,然后join大表.
- opencart
1. Deleting english language, what happens? Disable English tab , category and products 1) Fir ...
- 在cmd里面使用mysql命令
1.先找出mysqld文件所在的位置,我的是在C:\Program Files\MySQL\MySQL Server 5.1\bin. 2.cd C:\Program Files\MySQL\MySQ ...
- 【Docker 命令】- pull命令
docker pull : 从镜像仓库中拉取或者更新指定镜像 语法 docker pull [OPTIONS] NAME[:TAG|@DIGEST] OPTIONS说明: -a :拉取所有 tagge ...
- sublime text 输入法不跟随光标
1.引子 sublime text 有个BUG,那就是不支持中文的鼠标跟随(和PS类似输入的光标和文字候选框不在一起).如下图: 2.插件 安装IMESupport插件即可插件,这款插件是日本人写的. ...
- Tiny4412 LED 程序
package cn.hyc.led; import android.os.Bundle; import android.app.Activity; import android.view.Menu; ...
- java 基本--数据类型转换--001
小可转大,大转小可能会损失精度(编译出错,需要强制转换)A: byte,short,char -> int -> long -> float ->doubleB: byte,s ...