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(思维+强连通分量)的更多相关文章

  1. [HDOJ4635]Strongly connected(强连通分量,缩点)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给一张图,问最多往这张图上加多少条边,使这张图仍然无法成为一个强连通图. 起初是先分析样例 ...

  2. HDU 4635 Strongly connected(强连通分量,变形)

    题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...

  3. HDU 4635 Strongly connected ——(强连通分量)

    好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...

  4. HDU 4635 Strongly connected(强连通分量缩点+数学思想)

    题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...

  5. HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】

    Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  6. HDU 4635:Strongly connected(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给出n个点和m条边,问最多能添加几条边使得图不是一个强连通图.如果一开始强连通就-1.思路:把图分成 ...

  7. Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )

    题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...

  8. hdu 4635 Strongly connected(强连通)

    考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...

  9. HDU4635 Strongly connected【强连通】

    题意: 给一个n个点的简单有向图,问最多能加多少条边使得该图仍然是简单有向图,且不是强连通图.简单有向图的定义为:没有重边,无自环. 强连通图的定义为:整个图缩点后就只有一个点,里面包含n个原点,也就 ...

随机推荐

  1. leetcode-前K个高频元素

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], ...

  2. 深入理解 Vuejs 组件

    本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点.由于本人水平有限,如文中出现错误请多多包涵并指正,感谢.如果需要看更清晰的代码高亮,请跳转至我的个人站点的 深入理解 Vue ...

  3. 吴恩达j机器学习之过拟合

    五.编程作业: 见:https://www.cnblogs.com/tommyngx/p/9933803.html

  4. [leetcode-784-Letter Case Permutation]

    Given a string S, we can transform every letter individually to be lowercase or uppercase to create ...

  5. ArrayList中modCount的作用

    在ArrayList中有个成员变量modCount,继承于AbstractList. 这个成员变量记录着集合的修改次数,也就每次add或者remove它的值都会加1.这到底有什么用呢? 先看下面一段测 ...

  6. iOS- 如何从Boujour里解析出IP地址(sockaddr *的解析)?

    1.前言 之前有网友跟我留言说到: 如何从Boujour 解析完的数组里解析出ip地址? 因为Boujour本身解析完毕之后的addresses是一个数组 那我们如何从这个数组里解析出我们需要的IP地 ...

  7. loadrunner如何监控windows系统的资源

    1.测试客户端与服务器之间的网络,保证通信畅通 2.开启服务器端Windows中的如下两个服务,可见系统服务中查找,cmd输入:services.msc 如下图: Remote Registry需改为 ...

  8. [Redis]在.NET平台下的具体应用

    一.安装第三方驱动 PM> Install-Package ServiceStack.Redis 二.使用C#语言调用类库访问Redis

  9. MySQL、HBase、ES的特点和区别

    MySQL:关系型数据库,主要面向OLTP,支持事务,支持二级索引,支持sql,支持主从.Group Replication架构模型(本文全部以Innodb为例,不涉及别的存储引擎). HBase:基 ...

  10. Git 应用补丁报错 “sha1 information is lacking or useless”

    因为现场代码在客户局域网内,不能连接到公司网络,所以一般更新的时候都是打补丁, 然后在客户现场应用补丁,但是最近在应用补丁的时候出现了如下问题: ... fatal: sha1 information ...