hdu 4635 Strongly connected 强连通
给一个有向图, 问你最多可以加多少条边, 使得加完边后的图不是一个强连通图。
只做过加多少条边变成强连通的, 一下子就懵逼了
我们可以反过来想。
最后的图不是强连通, 那么我们一定可以将它分成两部分, 两部分中, 每一部分都是一个强连通分量。 然后两部分连接的情况一定是一部分的每个点向另一部分的每个点连边, 而没有反向边。 这样才能保证边数最多并且不是强连通。
我们设一部分点数为x, 另一部分为y。 那么显然x+y == n.
总点数为 x*(x-1) + y*(y-1)+xy。 前两项是每一部分内部的边数, 第三项是两部分之间的边。 化简完之后为n*n-n-xy. 所以我们要想答案越大, xy就越小。 要想xy越小, 显然x, y的差值应该尽可能大。
所以我们将原图缩点, 找到点数最少的一个联通块, 将它作为x。 剩下的所有点作为y。 然后问题就解决了。
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 1e5+;
int n, m, head[maxn], in[maxn], out[maxn], cnt, num, top, deep;
int scnt[maxn], s[maxn], low[maxn], dfn[maxn], st[maxn], instack[maxn];
pll ed[maxn];
struct node
{
int u, nextt, to;
}e[maxn*];
void tarjan(int u) {
dfn[u] = low[u] = ++deep;
instack[u] = ;
st[++top] = u;
for(int i = head[u]; ~i; i = e[i].nextt) {
int v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(instack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]) {
int v;
cnt++;
do {
v = st[top--];
instack[v] = ;
s[v] = cnt;
scnt[cnt]++;
} while (v != u);
}
}
void solve() {
for(int i = ; i <= n; i++)
if(!dfn[i])
tarjan(i);
if(cnt == ) {
puts("-1");
return ;
}
for(int i = ; i<m; i++) {
int u = s[ed[i].fi], v = s[ed[i].se];
if(u == v)
continue;
in[v]++;
out[u]++;
}
int ans = inf;
for(int i = ; i <= cnt; i++) {
if(in[i] == || out[i] == ) {
ans = min(ans, scnt[i]);
}
}
ll sum = 1LL*(n-)*n;
sum -= m;
sum -= 1LL * ans * (n - ans);
printf("%I64d\n", sum);
return ;
}
void add(int u, int v) {
e[num].to = v, e[num].nextt = head[u], head[u] = num++;
}
void init() {
mem1(head);
num = top = deep = cnt = ;
mem(instack);
mem(scnt);
mem(dfn);
mem(in);
mem(out);
}
void read() {
init();
cin>>n>>m;
int u, v;
for(int i = ; i < m; i++) {
scanf("%d%d", &u, &v);
ed[i] = mk(u, v);
add(u, v);
}
}
int main()
{
int t;
cin>>t;
for(int casee = ; casee <= t; casee++) {
read();
printf("Case %d: ", casee);
solve();
}
return ;
}
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 (强连通分量)
题意 给定一个N个点M条边的简单图,求最多能加几条边,使得这个图仍然不是一个强连通图. 思路 2013多校第四场1004题.和官方题解思路一样,就直接贴了~ 最终添加完边的图,肯定可以分成两个部X和Y ...
- 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 (2013多校4 1004 有向图的强连通分量)
Strongly connected Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 4635 Strongly connected (Tarjan+一点数学分析)
Strongly connected Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) ...
- hdu 4635 Strongly connected(强连通)
考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...
- HDU 4635 Strongly connected(强连通分量,变形)
题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...
随机推荐
- 获得android应用的版本号
在开发的过程中,需要获得版本号 private PackageInfo getVersion() { PackageManager packageManager = MyApplication.get ...
- JQ第一篇
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- JS 精粹(方法)
数组方法: 模拟队列的操作:push()/shift();unshift()/pop();模拟栈操作:push()/pop(); push()返回增加后的长度.unshift也是.pop和shift返 ...
- Android ImageView图片自适应
网络上下载下来的图片自适应:android:adjustViewBounds="true"(其详细解释在下面) <ImageView android:id=" ...
- VB.NET 内存指针和非托管内存的应用
介绍 Visual Basic 从来不像在C或C++里一样灵活的操纵指针和原始内存.然而利用.NET框架中的structures 和 classes,可以做许多类似的事情.它们包括 IntPtr, ...
- DRBD脑裂解决方法
1.查看主服务器 [root@master ~]# /etc/init.d/drbd status drbd driver loaded OK; device status: version: (ap ...
- LInux下安装jdk与环境配置与Webstorm的安装
个人比较喜欢Webstorm这款软件,但是毕设要做的网站打算在Linux下做,所以就想在Linux上装个Webstorm.刚开始下载好后运行提示没有装jdk,然后apt-get install来安装还 ...
- shell提示符显示git当前分支
编辑/etc/profile或者~/.bashrc 在行末添加如下内容 # 获取git当前分支 git_branch() { branch='' cd $PWD if [ -d '.git' ]; t ...
- UML-状态图,顺序图,活动图
一.编写用例文档 1.用例的内容: 用例编号 用例名 执行者 前置条件 后置条件 基本路径 扩展路径 字段列表 业务规则 ...
- /dev/console,/dev/null,/dev/tty
UNIX和Linux中比较重要的三个设备文件是:/dev/console,/dev/tty和/dev/null. 0 : /dev/console 这个设备代表的是系统控制台,错误信息和诊断信息通常 ...