1. /**
  2. problem: http://poj.org/problem?id=3177
  3. tarjan blog: https://blog.csdn.net/reverie_mjp/article/details/51704523
  4.  
  5. v 为下一结点, u为当前结点
  6. 如果low[v] > dfn[u] 则 边(u,v)为桥
  7. 缩点后剩下的所有边都为桥(缩点后即为树结构)
  8. 将叶子结点相连使其成为双联通分量为最优解
  9. 所以:
  10. 添加(leaf + 1) / 2 条边即可使图成为双联通图
  11. **/
  12. #include<stdio.h>
  13. #include<stack>
  14. #include<algorithm>
  15. using namespace std;
  16.  
  17. class Graphics{
  18. const static int MAXN = ;
  19. const static int MAXM = * ;
  20. private:
  21. struct Edge{
  22. int to, next;
  23. bool bridge;
  24. }edge[MAXM];
  25. struct Point{
  26. int dfn, low, color;
  27. }point[MAXN];
  28. int first[MAXN], sign, sumOfPoint, dfnNum, colorNum;
  29. bool vis[MAXN];
  30. stack<int> stk;
  31. void tarjan(int u, int preEdge = -){
  32. point[u].low = dfnNum;
  33. point[u].dfn = dfnNum ++;
  34. vis[u] = true;
  35. stk.push(u);
  36. for(int i = first[u]; i != -; i = edge[i].next){
  37. int to = edge[i].to;
  38. if((i^) == preEdge) continue; /// 由于是双向边,防止由该边跑回原来的点
  39. if(!point[to].dfn){
  40. tarjan(to, i);
  41. point[u].low = min(point[u].low, point[to].low);
  42. if(point[to].low > point[u].dfn){
  43. edge[i].bridge = true;
  44. edge[i^].bridge = true;
  45. }
  46. }else if(vis[to]){
  47. point[u].low = min(point[to].dfn, point[u].low);
  48. }
  49. }
  50. if(point[u].dfn == point[u].low){
  51. vis[u] = false;
  52. point[u].color = ++ colorNum;
  53. while(stk.top() != u){
  54. point[stk.top()].color = colorNum;
  55. vis[stk.top()] = false;
  56. stk.pop();
  57. }
  58. stk.pop();
  59. }
  60. }
  61. public:
  62. void init(int n){
  63. sumOfPoint = n;
  64. for(int i = ; i <= n; i ++){
  65. first[i] = -;
  66. vis[i] = ;
  67. }
  68. sign = colorNum = ;
  69. dfnNum = ;
  70. }
  71. void addEdgeOneWay(int u, int v){
  72. edge[sign].to = v;
  73. edge[sign].next = first[u];
  74. edge[sign].bridge = false;
  75. first[u] = sign ++;
  76. }
  77. void addEdgeTwoWay(int u, int v){
  78. addEdgeOneWay(u, v);
  79. addEdgeOneWay(v, u);
  80. }
  81. void tarjanAllPoint(){
  82. for(int i = ; i <= sumOfPoint; i ++){
  83. if(!point[i].dfn)
  84. tarjan(i);
  85. }
  86. }
  87. int getAns(){
  88. int *degree = new int[sumOfPoint+];
  89. int ans = ;
  90. for(int i = ; i <= sumOfPoint; i ++){
  91. degree[i] = ;
  92. }
  93. tarjanAllPoint();
  94. for(int i = ; i <= sumOfPoint; i ++){
  95. for(int j = first[i]; j != -; j = edge[j].next){
  96. int to = edge[j].to;
  97. if(edge[j].bridge){
  98. degree[point[to].color] ++;
  99. }
  100. }
  101. }
  102. for(int i = ; i <= sumOfPoint; i ++){
  103. if(degree[i] == ){
  104. ans ++;
  105. }
  106. }
  107. delete []degree; return (ans + ) / ;
  108. }
  109. }graph;
  110.  
  111. int main(){
  112. int f, r;
  113. scanf("%d%d", &f, &r);
  114. graph.init(f);
  115. while(r --){
  116. int a, b;
  117. scanf("%d%d", &a, &b);
  118. graph.addEdgeTwoWay(a, b);
  119. }
  120. printf("%d\n", graph.getAns());
  121. return ;
  122. }

ps:

  1. 防止由该边跑回原来的点不能判断(点)而要判断(边)即

  1. 这么写是有bug
    例如:重边

poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)的更多相关文章

  1. tarjan算法求桥双连通分量 POJ 3177 Redundant Paths

    POJ 3177 Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12598   Accept ...

  2. POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)

    POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...

  3. poj 3177 Redundant Paths(tarjan边双连通)

    题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...

  4. poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11047   Accepted: 4725 ...

  5. POJ 3177 Redundant Paths(边双连通的构造)

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13717   Accepted: 5824 ...

  6. POJ 3177——Redundant Paths——————【加边形成边双连通图】

    Redundant Paths Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  7. POJ 3177 Redundant Paths (tarjan边双连通分量)

    题目连接:http://poj.org/problem?id=3177 题目大意是给定一些牧场,牧场和牧场之间可能存在道路相连,要求从一个牧场到另一个牧场要有至少两条以上不同的路径,且路径的每条pat ...

  8. POJ 3177 Redundant Paths(Tarjan)

    题目链接 题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 . 思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1.然后找到所有叶子节点,即度数为1的节点的个数leaf ...

  9. POJ - 3177 Redundant Paths (边双连通缩点)

    题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...

随机推荐

  1. python爬取英语学习资料并发送邮件

    新建发送邮件类 import smtplib from email.mime.text import MIMEText from email.header import Header class Se ...

  2. 安装VS2013时,如何避开IE10的限制

    安装VS2013时,如何避开IE10的限制 VS就会告诉我们目前环境不适合安装VS2013,必须升级IE版本到IE10. 如果不想安装IE10,有没有办法呢? 答案肯定是有的. 将下面一段文字,储存为 ...

  3. 前端之CSS——盒子模型和浮动

    一.CSS盒子模型 HTML文档中的每个元素都被描绘成矩形盒子,这些矩形盒子通过一个模型来描述其占用空间,这个模型称为盒子模型. 盒子模型通过四个边界来描述:margin(外边距),border(边框 ...

  4. node:fs-extra模块

    var fs = require('fs-extra'); //复制 并会覆盖已有文件 fs.copy('./demo/index.html','./demo/index2.html' ,(err) ...

  5. Angular选项卡

    前几天我发的东西,可能对于没有基础的人很难理解,那么今天,咱们就发点简单点的东西吧! Angular显示隐藏,选项卡! 还是那句话,话不多说,上代码: <!DOCTYPE html> &l ...

  6. git本地分支重命名

    1. 本地分支重命名 git branch -m oldbranchname newbranchname 2. 远程分支重命名 (假设本地分支和远程对应分支名称相同) a. 重命名远程分支对应的本地分 ...

  7. hibernate_ID生成策略

    increment:主键按数值顺序递增.此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键.这种方式可能产生的问题是:如果当前有多个实例 ...

  8. 搭建JUnit环境

    1.下载 JUnit,这里用JUnit 4.7 下载链接: http://pan.baidu.com/s/1c23n7LQ 密码: i18e 2.可以直接 build path 引入:也可以创建 Us ...

  9. Oracle 查看session级别信息

    1. 查看活动会话信息[sql] view plain copySELECT *    FROM V$SESSION   WHERE USERNAME IS NOT NULL     AND STAT ...

  10. JS入口函数和JQuery入口函数

    首先,讲一下它们的区别: (1)JS的window.onload事件必须要等到所有内容,以及外部图片之类的文件加载完之后,才会去执行. (2)JQuery入口函数是在所有标签加载完之后,就会去执行. ...