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 四大组件之Activity生命周期
写这篇博文之前,已经对android有一定的了解和认识.这篇博文主要讲述android的Activity的生命周期,这是android开发者必须掌握的知识.android的Activity组件拥有7个 ...
- (七)Android中AIDL的应用与理解
一.跨应用启动Service Intent serviceIntent=new Intent();serviceIntent.setComponent(new ComponentName(" ...
- js糟粕
正在看<javascript语言精粹>,遇到明显的特点就记录下来,以防看了白看(噗噗~) 为了不误导,形成错误印象,文中 ‘错误设计‘ 写成 ‘现有设计’,’正确设计‘ 写成 ’期待设计‘ ...
- linux下socket编程-TCP
网络字节序 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定:先发出 ...
- EditPlus 快速去重
- js问题学习
1.前言为了node.js做准备,js的基本功还是很重要的.所以正值1024程序员节的时候所以找了些题目,整理了一下知识点.这篇文章感觉代码太多,难免枯燥,所以文章最后留了个彩蛋给读者. 2.简单回调 ...
- android Mvp简单实用
View 对应于Activity,负责View的绘制以及与用户交互Model 依然是业务逻辑和实体模型Presenter 负责完成View于Model间的交互 模拟客户端的登录操作,并实现登录成功与登 ...
- Android_实现静默安装和卸载应用
转:http://www.cnblogs.com/ondream/archive/2012/04/13/2446138.html 前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部 ...
- Flink Program Guide (7) -- 容错 Fault Tolerance(DataStream API编程指导 -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- 【转】MUD教程--巫师入门教程4
我们再次复习一下clean_up()函数返回1的含义,如果clean_up()函数返回1,则MUDOS在这一次的调用时不会做其的任何举动,但到了下一次想调用的时间里,还将再次调用这个对象的clean_ ...