题意:

一个有向图,问最少加几条边,能让它强连通

方法:

1:tarjan 缩点

2:采用如下构造法:

缩点后的图找到所有头结点和尾结点,那么,可以这么构造:把所有的尾结点连一条边到头结点,就必然可以是强连通了。如果说有几个结点不连通,那么让他们的尾结点相互只向对方的头结点就好了。

那么,最后的答案就是,头结点和尾结点中比较小的那个数量。

当然,如果缩点后只有一个点,那么就是0;

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define N 20010
using namespace std;
vector <int> to[N];
vector <int> g[N];
int in[N], out[N];
//#define vii vector<int>iterator;
int low[N], dep[N], id[N], s[N], top, scnt, cnt;
int n, m;
void tarinit() {
top = cnt = scnt = ;
memset(dep, -, sizeof(dep));
} void tarjan(int u) {
int minc = low[u] = dep[u] = cnt++;
s[top++] = u;
int end = to[u].size();
for (int i = ; i < end; i++) {
if (dep[to[u][i]] == -) tarjan(to[u][i]);
if (minc > low[to[u][i]]) minc = low[to[u][i]];
}
if (minc < low[u]) low[u] = minc;
else {
while (s[top] != u){
id[s[--top]] = scnt;
low[s[top]] = n+;
}
scnt++;
}
} int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) to[i].clear(), g[i].clear();
for (int i = ; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
to[u].push_back(v);
}
tarinit();
for (int i = ; i <= n; i++) {
if (dep[i] == -) {
tarjan(i);
}
}
memset(out,,sizeof(out));
memset(in,,sizeof(in));
for (int i = ; i <= n; i++) {
int end = to[i].size();
for (int j = ; j < end; j++) {
if (id[i] != id[to[i][j]]) {
out[id[i]]++;
in[id[to[i][j]]]++;
}
}
}
if (scnt == ) {
puts("");
continue;
}
int root = ;
int leaf = ;
for (int i = ; i < scnt; i++) {
if (out[i] == ) leaf++;
if (in[i] == ) root++;
}
printf("%d\n", max(root,leaf));
}
return ;
}

HDU 2767:Proving Equivalences(强连通)的更多相关文章

  1. hdu 2767 Proving Equivalences 强连通缩点

    给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...

  2. HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)

    Consider the following exercise, found in a generic linear algebra textbook. Let A be an n × n matri ...

  3. HDU 2767 Proving Equivalences (强联通)

    pid=2767">http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 40 ...

  4. hdu 2767 Proving Equivalences

    Proving Equivalences 题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边:问添加几条边可使图变 ...

  5. HDU 2767 Proving Equivalences(至少增加多少条边使得有向图变成强连通图)

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  6. HDU 2767 Proving Equivalences (Tarjan)

    Proving Equivalences Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other ...

  7. hdu - 2667 Proving Equivalences(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=2767 求至少添加多少条边才能变成强连通分量.统计入度为0的点和出度为0的点,取最大值即可. #include & ...

  8. hdu 2767 Proving Equivalences(tarjan缩点)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:问最少加多少边可以让所有点都相互连通. 题解:如果强连通分量就1个直接输出0,否者输出入度 ...

  9. hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. Your Ride Is Here

    纯粹的水题= = /* ID:yk652321 LANG:C++ TASK:ride */ #include<iostream> #include<cstring> #incl ...

  2. angular5 HttpInterceptor使用

    HttpInterceptor接口是ng的http请求拦截器,当需要拦截http请求,可以实现该接口. 1.创建HttpInterceptor 的实现类,并使用@Injectable()注解 @Inj ...

  3. Python基础——时间

    导入时间模块 import time 时间戳 print(time.time()) 获取本地时间 print(time.localtime(time.time())) 时间显示格式化 print(ti ...

  4. STM32CUBEMX入门学习笔记3:HAL库以及STM32CUBE相关资料

    微雪课堂:http://www.waveshare.net/study/article-629-1.html 之前的正点原子的例程资料 硬石科技stm32cube: 链接:https://pan.ba ...

  5. Java并发编程的艺术 记录(二)

    volatile的应用 volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量.Java语言提供了volatil ...

  6. Codeforces Round #505 D. Recovering BST(区间DP)

    首先膜一发网上的题解.大佬们tql. 给你n个单调递增的数字,问是否能够把这些数字重新构成一棵二叉搜索树(BST),且所有的父亲结点和叶子结点之间的gcd > 1? 这个题场上是想暴力试试的.结 ...

  7. LightOj:1030-Discovering Gold(期望dp模板)

    传送门:http://www.lightoj.com/volume_showproblem.php?problem=1030 Discovering Gold Time Limit: 2 second ...

  8. 水题:HDU1716-排列2

    排列2 Problem Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数. Input 每组数据占一行,代 ...

  9. poj 2376 选择工作区间问题 贪心算法

    题意:给一些工作区间,如何选取最小的工作数量,覆盖[1,T]的工作时长 一开始的思路,当然也是错误的思路: 我想着,最小工作数量是吧?那肯定就是选择结束时间最晚的,给结束时间来一个排序.哎这个思路错误 ...

  10. 求数组中两两相加等于20的组合(Python实现)

    题目 求数组中两两相加等于20的组合. 例:给定一个数组[1, 7, 17, 2, 6, 3, 14],这个数组中满足条件的有两对:17+3=20, 6+14=20. 解析 分为两个步骤: 先采用堆排 ...