LINK


题目大意

给你一个有重边的无向图图,问你最少连接多少条边可以使得整个图双联通

思路

就是个边双的模板

注意判重边的时候只对父亲节点需要考虑

你就dfs的时候记录一下出现了多少条连向父亲的边就可以了

然后和有向图不一样的是,在这里非树边的更新不用判断点是不是在栈内,因为无向图中没有u可以到达v但是v不能到达u的情况


  1. //Author: dream_maker
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<stack>
  7. using namespace std;
  8. //----------------------------------------------
  9. //typename
  10. typedef long long ll;
  11. //convenient for
  12. #define fu(a, b, c) for (int a = b; a <= c; ++a)
  13. #define fd(a, b, c) for (int a = b; a >= c; --a)
  14. #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
  15. //inf of different typename
  16. const int INF_of_int = 1e9;
  17. const ll INF_of_ll = 1e18;
  18. //fast read and write
  19. template <typename T>
  20. void Read(T &x) {
  21. bool w = 1;x = 0;
  22. char c = getchar();
  23. while (!isdigit(c) && c != '-') c = getchar();
  24. if (c == '-') w = 0, c = getchar();
  25. while (isdigit(c)) {
  26. x = (x<<1) + (x<<3) + c -'0';
  27. c = getchar();
  28. }
  29. if (!w) x = -x;
  30. }
  31. template <typename T>
  32. void Write(T x) {
  33. if (x < 0) {
  34. putchar('-');
  35. x = -x;
  36. }
  37. if (x > 9) Write(x / 10);
  38. putchar(x % 10 + '0');
  39. }
  40. //----------------------------------------------
  41. const int N = 5e3 + 10;
  42. const int M = 1e4 + 10;
  43. struct Edge {
  44. int u, v, nxt;
  45. } E[M << 1];
  46. int head[N], tot = 0;
  47. int n, m, du[N];
  48. void add(int u, int v) {
  49. ++tot;
  50. E[tot].u = u;
  51. E[tot].v = v;
  52. E[tot].nxt = head[u];
  53. head[u] = tot;
  54. }
  55. int dfn[N], low[N], bel[N], ind = 0, cnt_bcc = 0;
  56. stack<int> st;
  57. void tarjan(int u, int fa) {
  58. dfn[u] = low[u] = ++ind;
  59. st.push(u);
  60. bool k = 0;
  61. for (int i = head[u]; i; i = E[i].nxt) {
  62. int v = E[i].v;
  63. if (fa == v && !k) {
  64. k = 1;
  65. continue;
  66. }
  67. if (!dfn[v]) {
  68. tarjan(v, u);
  69. low[u] = min(low[u], low[v]);
  70. } else {
  71. low[u] = min(low[u], dfn[v]);
  72. }
  73. }
  74. if (low[u] == dfn[u]) {
  75. int now;
  76. ++cnt_bcc;
  77. do {
  78. now = st.top(); st.pop();
  79. bel[now] = cnt_bcc;
  80. } while (now != u);
  81. }
  82. }
  83. int main() {
  84. Read(n), Read(m);
  85. fu(i, 1, m) {
  86. int u, v;
  87. Read(u), Read(v);
  88. add(u, v);
  89. add(v, u);
  90. }
  91. fu(i, 1, n) if (!dfn[i]) tarjan(i, 0);
  92. for (int i = 1; i <= tot; i += 2) {
  93. int u = E[i].u, v = E[i].v;
  94. if (bel[u] != bel[v]) {
  95. du[bel[u]]++;
  96. du[bel[v]]++;
  97. }
  98. }
  99. int ans = 0;
  100. fu(i, 1, cnt_bcc)
  101. if (du[i] == 1) ans++;
  102. ans = (ans + 1) >> 1;
  103. Write(ans);
  104. return 0;
  105. }

POJ3177 Redundant Paths【tarjan边双联通分量】的更多相关文章

  1. POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】

    LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...

  2. [J]computer network tarjan边双联通分量+树的直径

    https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...

  3. POJ 3177 Redundant Paths 无向图边双联通基础题

    题意: 给一个无向图,保证任意两个点之间有两条完全不相同的路径 求至少加多少边才能实现 题解: 得先学会一波tarjan无向图 桥的定义是:删除这条边之后该图不联通 一条无向边(u,v)是桥,当且仅当 ...

  4. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  5. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  6. poj-3177(并查集+双联通分量+Tarjan算法)

    题目链接:传送门 思路: 题目要将使每一对草场之间都有至少两条相互分离的路径,所以转化为(一个有桥的连通图至少加几条边才能变为双联通图?) 先求出所有的桥的个数,同时将不同区块收缩成一个点(利用并查集 ...

  7. tarjan求双联通分量(割点,割边)

    之前一直对tarjan算法的这几种不同应用比较混淆...我太弱啦! 被BLO暴虐滚过来 用tarjan求点双,很多神犇都给出了比较详细的解释和证明,在这里就不讲了(其实是这只蒟蒻根本不会orz) 这里 ...

  8. POJ3177 Redundant Paths(边双连通分量+缩点)

    题目大概是给一个无向连通图,问最少加几条边,使图的任意两点都至少有两条边不重复路径. 如果一个图是边双连通图,即不存在割边,那么任何两个点都满足至少有两条边不重复路径,因为假设有重复边那这条边一定就是 ...

  9. poj3352 Road Construction & poj3177 Redundant Paths (边双连通分量)题解

    题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后 ...

随机推荐

  1. python selenium 安装与 chromedriver安装

    安装 pip install selenium 安装完成之后运行脚本,如果没报错那ok.但是很不幸运,我报错啦.(本人使用ubuntu16.04,python2,or python3) 贴出我的报错: ...

  2. C语言中exit函数的使用

      exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一 ...

  3. 77. Combinations(回溯)

    Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. Example: I ...

  4. Python tricks(1) -- 动态定义一个新变量

    python是动态语言, 无需声明变量即可使用. 传递一个tuple, list或者dict等等方式, 有时候这种方式的使用不是很好. 对于tuple和list来说都是用下标的访问方式(即使用[]), ...

  5. JS实现弹出层效果

    很多时候我们想去某某网站干点什么的时候,就会让我们先注册登录后才可以访问内容,而现在很多网站注册登录的时候都会有一种遮罩层的效果,就是背景是带有透明度的黑色遮罩,盖满整个网站,然后登录框弹出固定在屏幕 ...

  6. Spring Data JPA中CrudRepository与JpaRepository的不同

    使用Spring Data JPA CrudRepository 和JpaRepository 的好处: 继承这些接口,可以使Spring找到自定义的数据库操作接口,并生成代理类,后续可以注入到Spr ...

  7. 【转载】hibernate缓存机制

    一级缓存(session级别) 我们来看看hibernate提供的一级缓存 //此时会发出一条sql,将所有学生全部查询出来,并放到session的一级缓存当中.当再次查询学生信息时,会首先去缓存中看 ...

  8. [Pytorch]Pytorch 细节记录(转)

    文章来源 https://www.cnblogs.com/king-lps/p/8570021.html 1. PyTorch进行训练和测试时指定实例化的model模式为:train/eval eg: ...

  9. C++函数的返回值——返回引用类型&非引用类型

    函数的返回主要分为以下几种情况: 1.主函数main的返回值: 允许主函数main没有返回值就可结束:可将主函数main返回的值视为状态指示器,返回0表示程序运行成功,其他大部分返回值则表示失败. 2 ...

  10. POJ 2699 The Maximum Number of Strong Kings (最大流+枚举)

    http://poj.org/problem?id=2699 题意: 一场联赛可以表示成一个完全图,点表示参赛选手,任意两点u, v之间有且仅有一条有向边(u, v)或( v, u),表示u打败v或v ...