HDU 4635 Strongly connected(强连通分量,变形)
题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通。
思路:
强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量。
在使图不强连通的前提下,要添加尽可能多的边。边至多有n*(n-1)条,而已经给了m条,那么所能添加的边数不可能超过k=n*(n-1)-m。
这k条边还有部分不能添加,一添加立刻就强连通。一个强连通图最少只需要n条边,根据强连通的特性,缩点之后必定是不会有环的存在的,那么只要继续保持没有环的存在即可。我们只要让其中1个强连通分量没有出度,或者没有入度就行了。到底选哪个强连通分量?选点数少的,这点在后面会了解。因为1*10=10,而2*9=18啊,也就是两个数越接近,两者之积越大。
如果挑出1个出度(入度也行的,同理)为0的强连通分量,该强连通分量的点数为d,那么答案就是k-d*(n-d),即不允许有其他n-d个点有任何一条边指向此强连通分量,其他边都是可以存在的。那么要使得k-d*(n-d)最大,那么d*(n-d)要最小,就是上面讲的要选哪个强连通分量的原因。
那么应该找到缩点后出/入度为0的且包含点数最少的强连通分量来计算即可。
#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
using namespace std;
const int N=+;
const int INF=0x7f7f7f7f;
vector<int> vect[N];
stack<int> stac;
int num[N], chu[N], ru[N]; //统计强连通分量中点的个数
int scc_no[N], lowlink[N], dfn[N], dfn_clock, scc_cnt; //SCC必备
int n, m;
unordered_map<int,int> mapp;
void DFS(int x) //常规tarjan
{
stac.push(x);
dfn[x]=lowlink[x]=++dfn_clock;
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!dfn[t])
{
DFS(t);
lowlink[x]=min(lowlink[x],lowlink[t]);
}
else if(!scc_no[t]) //如果t不属于任何一个强连通分量
lowlink[x]=min(lowlink[x],dfn[t]);
}
if(lowlink[x]==dfn[x])
{
scc_cnt++;
while(true)
{
int t=stac.top();
stac.pop();
scc_no[t]=scc_cnt;
//scc[scc_cnt].push_back(t);
if(t==x) break;
}
}
} LL cal()
{
memset(dfn,,sizeof(dfn));
memset(lowlink,,sizeof(lowlink));
memset(scc_no,,sizeof(scc_no)); dfn_clock=scc_cnt=;
for(int i=; i<=n; i++) if(!dfn[i]) DFS(i); //深搜
if(scc_cnt==) return -; //已经强连通 memset(chu,,sizeof(chu));
memset(ru,,sizeof(ru));
for(int i=; i<=n; i++) //统计出入度数量
for(int j=; j<vect[i].size(); j++)
if(scc_no[i]!=scc_no[vect[i][j]] ) chu[scc_no[i]]=ru[scc_no[vect[i][j]]]=true; memset(num,,sizeof(num));
for(int i=; i<=n; i++) num[scc_no[i]]++; //统计每个scc中的点的数目
int small=INF;
for(int i=; i<=scc_cnt; i++) if(!chu[i]||!ru[i]) small=min(small,num[i]);//挑量小的,只要满足出/入度为0。如果都已经有出和入度了,那还计算啥!
return (LL)n*(n-) - m - small*(n-small); //注意10万*10万
} int main()
{
freopen("input.txt", "r", stdin);
int a, b, t, j=;
cin>>t;
while(t--)
{
scanf("%d%d",&n,&m);
mapp.clear();
int up=;
for(int i=; i<=n; i++) vect[i].clear();
for(int i=; i<m; i++)
{
scanf("%d%d", &a, &b);
if(!mapp[a]) mapp[a]=++up; //只是怕点号不连续,好像多余了
if(!mapp[b]) mapp[b]=++up;
vect[mapp[a]].push_back(mapp[b]);
}
printf("Case %d: %lld\n",++j,cal());
}
return ;
}
AC代码
HDU 4635 Strongly connected(强连通分量,变形)的更多相关文章
- HDU 4635 Strongly connected (强连通分量)
题意 给定一个N个点M条边的简单图,求最多能加几条边,使得这个图仍然不是一个强连通图. 思路 2013多校第四场1004题.和官方题解思路一样,就直接贴了~ 最终添加完边的图,肯定可以分成两个部X和Y ...
- HDU 4635 Strongly connected (强连通分量+缩点)
<题目链接> 题目大意: 给你一张有向图,问在保证该图不能成为强连通图的条件下,最多能够添加几条有向边. 解题分析: 我们从反面思考,在该图是一张有向完全图的情况下,最少删去几条边能够使其 ...
- hdu 4635 Strongly connected 强连通缩点
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...
- HDU 4635 Strongly connected(强连通)经典
Strongly connected Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- hdu 4635 Strongly connected 强连通
题目链接 给一个有向图, 问你最多可以加多少条边, 使得加完边后的图不是一个强连通图. 只做过加多少条边变成强连通的, 一下子就懵逼了 我们可以反过来想. 最后的图不是强连通, 那么我们一定可以将它分 ...
- HDU 4635 Strongly connected (2013多校4 1004 有向图的强连通分量)
Strongly connected Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 4635 - Strongly connected(2013MUTC4-1004)(强连通分量)
t这道题在我们队属于我的范畴,最终因为最后一个环节想错了,也没搞出来 题解是这么说的: 最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数尽可能的多,则X部肯 ...
- HDU 4635 Strongly connected ——(强连通分量)
好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...
- HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】
Strongly connected Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
随机推荐
- Linux进程间通信IPC学习笔记之管道
基础知识: 管道是最初的Unix IPC形式,可追溯到1973年的Unix第3版.使用其应注意两点: 1)没有名字: 2)用于共同祖先间的进程通信: 3)读写操作用read和write函数 #incl ...
- 配置node与express初试
http://www.nodejs.org/下载对应系统的node版本并安装 用npm包管理器安装需要的包 sudo npm install -g express sudo npm install - ...
- Unity3d之Http通讯GET方法和POST方法
(一)GET方法 IEnumerator SendGet(string _url) { WWW getData = new WWW(_url); yield return getData; if(ge ...
- 【BZOJ 1563】 [NOI2009]诗人小G
Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...
- Datatables中文API——回调函数
fnCookieCallback:还没有使用过 $(document).ready(function () { $('#example').dataTable({ "fnCookieCall ...
- 深入浅出百度地图API开发系列(3):模块化设计
在前面两张简单介绍了百度地图API的基础知识和使用之后,我们来分析一下百度地图API的基本架构,了解一下基本架构可以帮助我们更清晰的了解API的功能和调用过程,也就可以帮助我们在实际开发中可以更方便的 ...
- 3140:[HNOI2013]消毒 - BZOJ
题目描述 Description 最近在生物实验室工作的小 T 遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为 a*b*c,a.b.c均为正整数.为了实验的方便,它被划 ...
- NOI考前乱写
还有13天NOI,把各种乱七八糟的算法都重新过一遍还是比较有必要的... //HDU 5046 Airport //DancingLink #include<iostream> #incl ...
- LA 4731
dp[i][j]意思是前i个分成j组最小的花费 #include<cstdio> #include<algorithm> #include<cstring> #in ...
- python繁体中文到简体中文的转换
处理中文字符串遇到了繁体和简体中文的转换,python版: 1.下载zh_wiki.py及langconv zh_wiki.py:https://github.com/skydark/nstool ...