俩个题一样。tarjan算法应用,开始求桥,WA,同一个边双连通分量中low值未必都相同,不能用此来缩点。后来用并查集来判断,若不是桥,则在一个双连通分量中,并之,后边再查,将同一个双连通分量中的点通过并查集收缩为一个并查集的“祖宗点”,间接完成缩点!

缩点成树后,(leaves+1)/2就不用说了。。。。

  1. #include<iostream> //0MS
  2. #include<vector>
  3. #include<cstring>
  4. #include<cstdio>
  5. using namespace std;
  6. /*struct gebian //开始时记录割边,然后用同一个连通分量中LOW值相等来判断,错误。
  7. {
  8. int u,v;
  9. };*/
  10. vector<vector<int> >edge(5001); //相当于链表,这个真心不错。
  11. //vector<gebian>geb;
  12. int dfn[5001];
  13. int low[5001];
  14. int visited[5001]; //标记访问
  15. int time=0; //时间戳
  16. int degree[5001];
  17. int father[5001];
  18. int hash[5001][5001];
  19. int min(int a,int b)
  20. {
  21. if(a<=b)return a;
  22. return b;
  23. }
  24. int find(int x){return x==father[x]?x:find(father[x]);}
  25. void tarjan(int u,int fa) //dfs
  26. {
  27. dfn[u]=low[u]=++time;
  28. int daxiao=edge[u].size();
  29. for(int i=0;i<daxiao;i++)
  30. {
  31. int child=edge[u][i];
  32. if(visited[child]==0)
  33. {
  34. visited[edge[u][i]]=1;
  35. tarjan(edge[u][i],u);
  36. low[u]=min(low[u],low[edge[u][i]]);
  37. if(dfn[u]<low[edge[u][i]]) //是桥
  38. {
  39. /* gebian temp;
  40. temp.u=u;
  41. temp.v=edge[u][i];
  42. geb.push_back(temp);*/
  43. ;
  44. }
  45. else //不是桥,必在同一边连通分量中
  46. {
  47. father[child]= u; //并之
  48. }
  49. }
  50. else if(edge[u][i]!=fa)
  51. {
  52. low[u]=min(dfn[edge[u][i]],low[u]);
  53. }
  54. }
  55. }
  56. int solve(int n)
  57. {
  58. int leaves=0;
  59. //int daxiao1=geb.size();
  60. // cout<<daxiao1<<endl;
  61. /* for(int i=0;i<daxiao1;i++)
  62. {
  63. // cout<<low[geb[i].v]<<endl;
  64. // cout<<low[geb[i].u]<<endl;
  65. degree[low[geb[i].v]]++;
  66. degree[low[geb[i].u]]++;
  67. }
  68. for(int i=1;i<=n;i++)
  69. {
  70. cout<<low[i]<<" ";
  71. degree[low[i]]++;
  72. }*/
  73. for(int i=1;i<=n;i++) //枚举边
  74. {
  75. int len=edge[i].size();
  76. for(int j=0;j<len;j++)
  77. {
  78. if( hash[i][edge[i][j]]||hash[edge[i][j]][i])continue; //hash判重
  79. int xx=find(i);int yy=find(edge[i][j]);
  80. hash[i][edge[i][j]]=1;hash[edge[i][j]][i]=1;
  81. if(xx!=yy)
  82. {
  83. degree[xx]++;
  84. degree[yy]++;
  85. }
  86. }
  87. }
  88. for(int i=1;i<=n;i++)
  89. {
  90.  
  91. if(degree[i]==1) //叶子
  92. {
  93. leaves++;
  94. }
  95. }
  96. return (leaves+1)/2;
  97. }
  98. int main()
  99. {
  100. int n,m;
  101. scanf("%d%d",&n,&m);
  102. int a,b;
  103. for(int i=0;i<=n;i++)
  104. father[i]=i;
  105. for(int i=0;i<m;i++)
  106. {
  107. scanf("%d%d",&a,&b);
  108. edge[a].push_back(b);
  109. edge[b].push_back(a);
  110. }
  111. visited[1]=1;
  112. tarjan(1,-1);
  113. cout<<solve(n)<<endl;
  114. return 0;
  115. }

POJ3177,/3352.求最少添加多少边使无向图边双连通的更多相关文章

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

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

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

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

  3. poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)

    /** problem: http://poj.org/problem?id=3177 tarjan blog: https://blog.csdn.net/reverie_mjp/article/d ...

  4. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  5. hdoj 3836 Equivalent Sets【scc&&缩点】【求最少加多少条边使图强连通】

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

  6. LeetCode 921. 使括号有效的最少添加(Minimum Add to Make Parentheses Valid) 48

    921. 使括号有效的最少添加 921. Minimum Add to Make Parentheses Valid 题目描述 给定一个由 '(' 和 ')' 括号组成的字符串 S,我们需要添加最少的 ...

  7. 给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。

    题目描述: 给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除. 输入: 两个整数n(2<=n<=1000),a(2<=a<=1000) 输出: 一个整数. ...

  8. HDU 1326 Box of Bricks(水~平均高度求最少移动砖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1326 题目大意: 给n堵墙,每个墙的高度不同,求最少移动多少块转使得墙的的高度相同. 解题思路: 找到 ...

  9. 输入一个数字n 如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数 写出一个函数

    题目: 输入一个数字n  如果n为偶数则除以2,若为奇数则加1或者减1,直到n为1,求最少次数  写出一个函数 首先,这道题肯定可以用动态规划来解, n为整数时,n的解为 n/2 的解加1 n为奇数时 ...

随机推荐

  1. iOS开发XML解析

    xml解析主要可以使用CData,libxml2以及NSXMLParser,以下对各个方法给出了相应的例子: 1.CDataXML: 1.1.创建FKBook类 #import <Foundat ...

  2. C# 获取本机IP(优化项目实际使用版)

    好一段时间没来更新博客了,因为密码实在记不住,烦死了,密码干脆直接用那个找回密码链接的一部分. 吐槽完说正事了,关于C#  获取本机IP的,最开始用的是下面的,但是因为获取IP的有点多,而且难判断,忽 ...

  3. 技术抄录_Java高级架构师教程

    1.B2C商城项目实战     2.高性能架构专题     3.架构筑基与开源框架解析专题     4.团队协作开发专题     5.微服务架构专题     6.设计模式     附上[架构资料]   ...

  4. vue 高度 动态更新计算 calcHeight watch $route

    vue 高度 动态更新计算 calcHeight () { // this.tableHeight = window.innerHeight - 210 } }, mounted () { // co ...

  5. hard fault 学习记录

    使用 segger 的 hard fault 的源文件后,当调试时,发生硬件错误的时候,可以查看 HardFaultRegs 中的内容,并对比 segger_HardFaultHandler.c 中的 ...

  6. gocode安装不上的解决办法

    mkdir -p $GOPATH/src/golang.org/x  //路径下创建此文件 cd $GOPATH/src/golang.org/x      //切换到此目录 git clone ht ...

  7. Python matlab octave 矩阵运算基础

    基础总结,分别在三种软件下,计算 求逆矩阵 矩阵转置 等运算,比较异同 例子:正规方程法求多元线性回归的最优解 θ=(XTX)-1XTY octave: pwd()当前目录 ones() zeros( ...

  8. P1357 花园 (矩阵快速幂+ DP)

    题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5  n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...

  9. ICPC-Beijing 2006 狼抓兔子

    题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...

  10. Django生成二维码

    1. 安装 pip install qrcode 安装Image包 pip install Image 1.1 在代码中使用 import qrcode img = qrcode.make('输入一个 ...