loj 1210 (求最少的加边数使得图变成强连通)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1210
思路:首先是缩点染色,然后重建并且统计新图中的每个点的入度和出度,于是答案就是max(入度为0的点的个数, 出度为0的点的个数,这里有一个trick就是如果scc_count == 1,那么应该输出0.
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <stack> 6 using namespace std; 7 8 const int MAXN = (20000 + 20); 9 int n, m, NE; 10 struct Edge { 11 int v, next; 12 } edge[MAXN << 2]; 13 14 int head[MAXN]; 15 void Insert(int u, int v) 16 { 17 edge[NE].v = v; 18 edge[NE].next = head[u]; 19 head[u] = NE++; 20 } 21 22 int cnt, scc_count; 23 int low[MAXN], dfn[MAXN], color[MAXN]; 24 bool mark[MAXN]; 25 stack<int >S; 26 27 void Tarjan(int u) 28 { 29 low[u] = dfn[u] = ++cnt; 30 mark[u] = true; 31 S.push(u); 32 for (int i = head[u]; i != -1; i = edge[i].next) { 33 int v = edge[i].v; 34 if (dfn[v] == 0) { 35 Tarjan(v); 36 low[u] = min(low[u], low[v]); 37 } else if (mark[v]) { 38 low[u] = min(low[u], dfn[v]); 39 } 40 } 41 if (low[u] == dfn[u]) { 42 scc_count++; 43 int v; 44 do { 45 v = S.top(); 46 S.pop(); 47 mark[v] = false; 48 color[v] = scc_count; 49 } while (u != v); 50 } 51 } 52 53 int Indegree[MAXN], Outdegree[MAXN]; 54 55 int main() 56 { 57 int _case, t = 1; 58 scanf("%d", &_case); 59 while (_case--) { 60 scanf("%d %d", &n, &m); 61 NE = 0; 62 memset(head, -1, sizeof(head)); 63 while (m--) { 64 int u, v; 65 scanf("%d %d", &u, &v); 66 Insert(u, v); 67 } 68 cnt = scc_count = 0; 69 memset(dfn, 0, sizeof(dfn)); 70 memset(mark, false, sizeof(mark)); 71 for (int i = 1; i <= n; i++) { 72 if (dfn[i] == 0) Tarjan(i); 73 } 74 memset(Indegree, 0, sizeof(Indegree)); 75 memset(Outdegree, 0, sizeof(Outdegree)); 76 for (int u = 1; u <= n; u++) { 77 for (int i = head[u]; i != -1; i = edge[i].next) { 78 int v = edge[i].v; 79 if (color[u] != color[v]) { 80 Indegree[color[v]]++; 81 Outdegree[color[u]]++; 82 } 83 } 84 } 85 int ans1 = 0, ans2 = 0; 86 for (int i = 1; i <= scc_count; i++) { 87 if (Indegree[i] == 0) ans1++; 88 if (Outdegree[i] == 0) ans2++; 89 } 90 printf("Case %d: ", t++); 91 if (scc_count == 1) { 92 puts("0"); 93 } else 94 printf("%d\n", max(ans1, ans2)); 95 } 96 return 0; 97 } 98 99 100
View Code
转载于:https://www.cnblogs.com/wally/p/3529842.html
loj 1210 (求最少的加边数使得图变成强连通)相关推荐
- HDU 4635 Strongly connected(缩点、最多可加边数使得仍然非强连通)
整理的算法模板合集: ACM模板 HDU 4635 Strongly connected Give a simple directed graph with N nodes and M edges. ...
- 有向图转强连通图最少加边数
原文链接 问题描述 对于一有向图,若需要保证任选一点即可走到其它所有点,询问最少需要加多少条有向边 结论 对于一有向图,若其对应DAG中入度为0的点数为ppp,出度为0的点数为qqq,则答案数为max ...
- 求最少需要多少步可以变为Fibonacci数
目录 一.题目 二.思路 三.代码实现 一.题目 Fibonacci数列是这样定义的: F[0] = 0 F[1] = 1 for each i ≥ 2: F[i] = F[i-1] + F[i-2] ...
- 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数
输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数 题目: 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写 ...
- [JAVA]给你一个数N求最少需要多少步可以变为Fibonacci数
链接:https://www.nowcoder.com/questionTerminal/18ecd0ecf5ef4fe9ba3f17f8d00d2d66?pos=11&orderByHotV ...
- MODE —— 输入一个数字,求从1加到该数的和(知识点:for循环嵌套while循环)
问题描述: 终端输入一个数字,求从1加到这个数字的和! 运行结果: 代码部分: #include <stdio.h> int main() {unsigned int sum = 1UL; ...
- 求3000以内的亲密数C语言
题目要求:求3000以内的亲密数 这道题我第一做的时候我发现我直接就输出所有的亲密数,而说实话,按照题目的意思,A和B是不能相等的.所以我第一次做错了.这是我修改完的代码.当然主要思想还是没有变化. ...
- html中怎么远程控制小车,利用ESP8266远程控制小车 求大佬帮忙加段程序
求大佬帮忙加段程序,利用ESP8266远程控制小车,ESP8266做为热点,手机连接ESP8266的热点,然后用手机TCP进行远程连接.现在程序可以做到发送我要的数据,我现在要加段程序,使得我在手机上 ...
- 容斥原理之求区间中与某数互质的个数
一,定义 为了计算时不重不漏,就要不断加减重复部分 观察到:即奇数长度的前面是加号,偶数长度的为减号 二,思路:我们这里可以通过求不互质的数,自然就能得出互质的数,求不互质比较简单(因为他们是目标的质 ...
最新文章
- 2020-11-10(service入门)
- C语言图形化编程 【二】
- nginx服务器配置安全维护,Nginx服务器相关的一些安全配置建议
- Linux内核分析学习路线总结(内核人员必看)
- html5 判断页面加载,js判断页面是否加载完成的方法
- 小程序 学习。。。[个人感觉吧 官方文档写的相当详细了。。]
- 图像处理的相关数学知识
- 实测对比:2层和4层板的干扰和辐射差异
- POI-HSSFWorkbook合并单元格边框及文字居中问题
- 谷歌浏览器自带的谷歌翻译无法使用的解决办法
- win7系统笔记本做无线路由器
- 如何高效地引导自己的行为
- cocos 拼图思路
- java复习总结查漏补缺,三个月后准备开面【准备篇】
- ForkJoinPool的理解与使用
- 实现手机归属地查询页面
- 交通局信息上报“二次录入”难题交给博为小帮!
- c语言实现明明的随机数,明明的随机数 (C语言代码)
- 最新最详细Android SDK下载安装与配置
- 怎么把移动硬盘挂载到linux,linux 如何挂载移动硬盘