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个 ...
- C#文件读写操作
方法1:使用FileStream读写文件 using System;using System.Collections.Generic;using System.Text;using System.IO ...
- .Net 发邮件
对于.NET而言,从2.0开始,发邮件已经是一件非常easy 的事了.下面我给出一个用C#群发邮件的实例,做了比较详细的注解,希望对有需要的朋友有所help. // 引入命名空间using Syste ...
- VS2008 自动化编译脚本
可以通过调用MSBuild来使VS2008进行自动化编译. 1.新建文本文件,后缀名改为bat 2.文件内加上: ;转到MSBuild.exe路径 c: cd\ cd C:\Windows\Micro ...
- 用SQL将查询出来的多列的值拼接成一个字符串【转载】
MySQL中: [sql] view plaincopyprint? -- 单列拼接,先查出一行,再加上逗号,接着拼接 查出的下一行 select group_concat(E.SUPPORT) fr ...
- 【转】MUD教程--巫师入门教程4
我们再次复习一下clean_up()函数返回1的含义,如果clean_up()函数返回1,则MUDOS在这一次的调用时不会做其的任何举动,但到了下一次想调用的时间里,还将再次调用这个对象的clean_ ...
- java小型科学计算器
/** * 1.先转换为逆波兰顺序 * 数字直接存入list,符号压入栈中,但是如果栈底元素不大于该运算符的运算顺序,则将栈底pop,直到大于栈底运算符为止,再压入栈中, * 最后将运算符依次全部po ...
- php 汉字转换成拼音
class PinYin { private static $__data = array(); private static $__init = false; private static func ...
- delphi 文件搜索,遍历所有子目录
function ListFiles(path: string): TStringList; var SearchRec: TSearchRec; found: integer; begin resu ...
- Log4Net不生成日志文件
可能没有初始化配置,在Global文件Application_Start添加 log4net.Config.XmlConfigurator.Configure(); 或者输出日志进行初始化,如(Log ...