对于一个无向图,如果任意两点至少存在两条点不重复(除起点和终点外无公共点)的路径,则这个图就是点双联通。

这个要求等价于任意两条边都存在于一个简单环(即同一个点不能在圈中出现两次)中,即内部无割点。

那么算法首先要求出割点。

从代码中可以看出:只要求出割点,就开始组一个bcc中。

如果割点两侧都不存在环的话会怎么处理呢?

代码中相邻的割点(或者是割点和根节点)也被当做一个bcc处理。

bccno[i]为点i所在的bcc序号,那么割点的bccno为多少呢?

割点的bccno没有意义,割点存在于多个bcc中。

割点:删除这个点后,联通分量增加,那么这个点就是割点。

在图的dfs搜索树中,非根节点u的子节点v没有方向边(dfs搜索树中后代指向祖先的边)返回u的祖先,那么u就是割点。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<map>
  7. #include<stack>
  8. #include<vector>
  9. using namespace std;
  10. const int MAXN=1e3+,INF=0x3f3f3f3f,MOD=1e9+;
  11. int n;
  12. int vis[MAXN][MAXN];
  13. vector<int>G[MAXN];
  14. int dfs_color=; ///dfs时间戳
  15. int pre[MAXN],post[MAXN];
  16. int bcc_cnt=; ///联通分量
  17. int low[MAXN]; ///u及其后代所能连回的最早祖先的pre值
  18. int iscut[MAXN]; ///割点
  19. vector<pair<int,int> >birdge; ///桥
  20. struct edge
  21. {
  22. int u,v;
  23. };
  24. stack<edge>S;
  25. int bccno[MAXN]; ///点所在的双联通分量
  26. vector<int>bcc[MAXN]; ///双联通分量
  27. int dfs(int u,int fa)
  28. {
  29. int lowu=pre[u]=++dfs_color;
  30. int child=;
  31. for(int i=; i<G[u].size(); i++)
  32. {
  33. int v=G[u][i];
  34. edge e=(edge)
  35. {
  36. u,v
  37. };
  38. if(!pre[v])
  39. {
  40. S.push(e);
  41. child++;
  42. int lowv=dfs(v,u);
  43. lowu=min(lowu,lowv);
  44. if(lowv>=pre[u])
  45. {
  46. iscut[u]=true;
  47. if(lowv>pre[u]) birdge.push_back(make_pair(u,v));
  48. bcc_cnt++;
  49. bcc[bcc_cnt].clear();
  50. while(!S.empty())
  51. {
  52. edge x=S.top();
  53. S.pop();
  54. if(bccno[x.u]!=bcc_cnt)
  55. {
  56. bcc[bcc_cnt].push_back(x.u);
  57. bccno[x.u]=bcc_cnt;
  58. }
  59. if(bccno[x.v]!=bcc_cnt)
  60. {
  61. bcc[bcc_cnt].push_back(x.v);
  62. bccno[x.v]=bcc_cnt;
  63. }
  64. if(x.u==u&&x.v==v) break;
  65. }
  66. }
  67. }
  68. else if(pre[v]<pre[u]&&v!=fa)
  69. {
  70. S.push(e);
  71. lowu=min(lowu,pre[v]);
  72. }
  73. }
  74. if(fa<&&child==) iscut[u]=;
  75. low[u]=lowu;
  76. return low[u];
  77. }
  78. void find_bcc()
  79. {
  80. bcc_cnt=;
  81. dfs_color=;
  82. memset(pre,,sizeof(pre));
  83. memset(iscut,,sizeof(iscut));
  84. memset(bccno,,sizeof(bccno));
  85. for(int i=; i<=n; i++)
  86. if(!pre[i]) dfs(i,-);
  87. }
  88. void init(int m)
  89. {
  90. memset(vis,,sizeof(vis));
  91. for(int i=; i<=n; i++) G[i].clear();
  92. birdge.clear();
  93. while(m--)
  94. {
  95. int u,v;
  96. scanf("%d%d",&u,&v);
  97. G[u].push_back(v);
  98. G[v].push_back(u);
  99. }
  100. }
  101. int main()
  102. {
  103. int m;
  104. while(scanf("%d%d",&n,&m))
  105. {
  106. init(m);
  107. find_bcc();
  108. for(int i=; i<=bcc_cnt; i++)
  109. {
  110. cout<<i<<":";
  111. for(int j=; j<bcc[i].size(); j++)
  112. cout<<bcc[i][j]<<" ";
  113. cout<<endl;
  114. }
  115. }
  116. return ;
  117. }

大白书中无向图的点双联通分量(BCC)模板的分析与理解的更多相关文章

  1. 无向图边双联通分量 tarjan 模板

    #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; const int MAXM = 500005 ...

  2. 点双联通分量(BCC)的正确姿势

    Tarjan求点双连通分量 - 李昊哲

  3. Spoj 2878 KNIGHTS - Knights of the Round Table | 双联通分量 二分图判定

    题目链接 考虑建立原图的补图,即如果两个骑士不互相憎恨,就在他们之间连一条无向边. 显而易见的是,如果若干个骑士在同一个点数为奇数的环上时,他们就可以在一起开会.换句话说,如果一个骑士被一个奇环包含, ...

  4. 『Tarjan算法 无向图的双联通分量』

    无向图的双连通分量 定义:若一张无向连通图不存在割点,则称它为"点双连通图".若一张无向连通图不存在割边,则称它为"边双连通图". 无向图图的极大点双连通子图被 ...

  5. 图连通性【tarjan点双连通分量、边双联通分量】【无向图】

    根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...

  6. 【UVA10972】RevolC FaeLoN (求边双联通分量)

    题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...

  7. HDU5409---CRB and Graph 2015多校 双联通分量缩点

    题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...

  8. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

  9. Tarjan 强连通分量 及 双联通分量(求割点,割边)

    Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1)         有向图的强联通分量 (2)         无向图的双联通分量(求割点,桥) ...

随机推荐

  1. 装python package 时,conda提示会升级python2到python3,那可能是你的windows不支持py2env下的此包。

    装python package 时,conda提示会升级python2到python3, 那可能是你的windows不支持py2env下的此包.比如:win 下,tensorflow就不支持py2的环 ...

  2. Hive实现交叉二维分析的小语句

    1. 梳理出你要的列和行维度 列维度: 每一周 行维度: 年级 + 学科 + 班型 2. 对数据按周增序进行聚合 (即根据列维度) ,生成list concat_ws 和 collect_list ( ...

  3. WEB日志分析工具(Webslizer和AWstats)

    https://www.cnblogs.com/xiaowenshu/p/10030139.html#top

  4. 关于前段JS代码报错问题的解决方法

    最近接手别人的一个项目,项目导入到Myeclipse中,JS代码一直报错,说missing semicolon.该错误是Myeclipse在检查JS代码的过程出现的. 后来经过检查,发现JS代码本身没 ...

  5. 分享自己用的php分页类实例源码

    分享一个我自己用着的php分页类实例源码,供大家参考,具体内容如下: <?php /** file: page.class.php 完美分页类 Page */ class Page { priv ...

  6. K2项目开发流程

    (自己的学习资料) K2项目开发流程: 1.在VS2013中设计流程,并在K2 Workspce中测试流程 首先是新建新建一个k2的Process文件..kprx后缀. 在里面创建所需要的流程.由于我 ...

  7. leetcode971

    class Solution: def flipMatchVoyage(self, root, voyage): res = [] self.i = 0 def dfs(root): if not r ...

  8. 运行UMAT:+ABQ和VS、IVF绑定

    运行UMAT: 1.run-script----xxxx.py2.属性---编辑材料---通用---非独立变量---用户材料3.job---编辑作业---通用----用户子程序.for4.parall ...

  9. Spring 整合WebSocket, Error during WebSocket handshake: Unexpected response code: 302 还有200的错误

    springboot 集成websocket 及其简单,,,但是管理端使用的是Spring,原生配置,发生这个错误,,,302 被重定向了...我起的是本地locallhost,把ip换成 local ...

  10. Java连接kafka

    1.maven依赖: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://ww ...