/*经过简单的使用,对刘汝佳的这个板做几个简单的说明:1、算法结束后每个bcc[i]里存入一个双连通分量的点的标号,其中割点也被存进去,也就是说割点可以属于多个双连通分量2、根据刘汝佳所说的点—双连通的要求,“任意两条边都在一个简单环中”,但是从代码中看到只要找到割点就要开始组一个连通分量了,那么问题就来了,如果割点的两侧都不是环呢?比如对一棵树来说,任一点都是割点,点的两侧都是一条边,没有环,那怎么算他的双连通分量呢?根据调试跟踪的结果,对一棵树来说一条边所关联的两点就是一个点双连通分量,也就是说,两个相邻的割点也各自被认作了一个双连通分量3、割点的bccno没有意义,因为割点属于多个双连通分量4、蓝书上认为没必要清空stack S,保险起见我给加上了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
const int maxn = 10000 + 5;
struct Edge
{int u, v;
};
int iscut[maxn], pre[maxn], bccno[maxn], dfs_clock, bcc_cnt;
vector<int>G[maxn], bcc[maxn];
stack<Edge>S;
int dfs(int u, int fa)
{int lowu = pre[u] = ++dfs_clock;int child = 0;for (int i = 0; i<G[u].size(); i++){int v = G[u][i];Edge e = { u, v };if (!pre[v]){S.push(e);child++;int lowv = dfs(v, u);lowu = min(lowv, lowu);if (lowv >= pre[u]){iscut[u] = 1;bcc_cnt++;  bcc[bcc_cnt].clear();for (;;){Edge x = S.top();       S.pop();if (bccno[x.u] != bcc_cnt){bcc[bcc_cnt].push_back(x.u);bccno[x.u] = bcc_cnt;}if (bccno[x.v] != bcc_cnt){bcc[bcc_cnt].push_back(x.v);bccno[x.v] = bcc_cnt;}/*造成上述第二条的一个重要原因就是这个判断放在了上面两个if语句之下,所以这条跳出边的两端点已被加入了bcc[bcc_cnt]中;另外,这条跳出的边是bcc内部的边,不是外部的边;*/if (x.u == u &&x.v == v){  break;}}}}else if (pre[v]<pre[u] && v != fa){S.push(e);lowu = min(lowu, pre[v]);}}if (fa < 0 && child == 1)    iscut[u] = 0;
/*这里可能会有一个疑问,既然根节点有可能不是割点,根节点所在的点联通分量岂不是会被漏掉了?其实,因为根节点满足lowv >= pre[root],所以在上面的判断中已经被视为一个割点,因此将他所在的连通分量作为一个点连通分量存储起来了,并且将其所关联得边从栈中清空,因此不会发生漏掉根节点所在连通分量的情况
*/  return lowu;
}
void find_bcc(int n)
{mem(pre, 0);mem(bccno, 0);mem(iscut, 0);while (!S.empty())   S.pop();dfs_clock = bcc_cnt = 0;for (int i = 1; i <= n; i++)if (!pre[i])         dfs(i, -1);
}

对刘汝佳蓝书点双连通分量(BCC)模板的理解相关推荐

  1. 刘汝佳蓝书后缀数组模板解释及补全

    相信很多初学后缀数组的ACMer在学习蓝书中的后缀数组部分遇到了一些障碍,可能像我一样看明白了P219 --220的讲解和算法,百度了基数排序的方法,然后被卡在P221的代码上了,本文目的即分享我对这 ...

  2. 刘汝佳紫书 uva1592

    刘汝佳上传的代码没耐心看...就大致照着书上写的思路写了一个...一开始发现全写错了耗了半天... 定义一个pair,这个pair里有存两个队,字符串对和int对.每每读入一行的时候看看map中是否存 ...

  3. UVa 11062 Andy's Second Dictionary(刘汝佳紫书升级题)

    在介绍这道题之前,先介绍一下紫书里面和这道题很像的一道题: 紫书P112页 的例题5-3 安迪的第一个字典(Andy's First Dictionary UVa 10815) 原题链接如下: And ...

  4. c语言 开灯问题,刘汝佳紫书[数组和字符串]内容总结

    本篇文章是笔者对紫书第3章--数组和字符串内容的一个整理,主要是基于问题的整理,总结并理顺了一下思路. 不得不说,这些题解真的是太巧妙了

  5. AC自动机模板(摘自刘汝佳紫书,无指针)

    本题的题目选择的是 病毒侵袭持续中 HDU - 3065 const int size=5e4+5; const int SIGMA_SIZE=26; int trie[size][26],val[s ...

  6. (精讲)UVA - 1339 Ancient Cipher 刘汝佳紫书题单(算法竞赛入门经典)

    仔细读题并且对比样例可以发现,字母的替换和换元的规律是不同的,所以不能用模拟法将原来的字符串找到进行比对,所以要从替换换元前后的特点来看. 替换: 替换前后的两个字母集合可以看作是一个映射: 例如 H ...

  7. 整理 刘汝佳紫书第三章习题代码 未完待续

    还有一会儿要去剑道社训练...就整理整理好了... 习题3-1 得分 UVA1585 代码: #include <iostream> using namespace std; int ma ...

  8. UVA - 489 Hangman Judge 刘汝佳紫书题单(算法竞赛入门经典)

    思路很简单,题目中说猜对目标字母中的一个字母,就会将所有该字母的位置显现,因此,可以对目标字符进行筛选去重,然后对输入猜测的每个字母进行比对,由于不能猜已经猜过的字母,因此,要对成功猜出的目标字母进行 ...

  9. UVA - 1225 Digit Counting(刘汝佳紫书题单(算法竞赛入门经典 第二版 2014)

    个人感觉这道题有表述问题 他的题目表述说明测试数据中的数是不超过20的,但其实他的测试点中是有百位数的,所以按两位数去处理数据显然会造成数组越界. 代码如下 #include <bits/std ...

最新文章

  1. Linux内核源码中使用宏定义的若干技巧
  2. Ubuntu 18.04 如何添加或删除 SWAP 交换分区
  3. windows结束线程的三种方式
  4. 数据去重复_字典应用实例(每行每列都要去重复值)
  5. linux 安装x环境,linux下安装xdebug
  6. 光纤交换机按照级别可分为3种
  7. akka 简介_Akka HTTP路由简介
  8. 【转】ABP源码分析三十六:ABP.Web.Api
  9. 福布斯中国2020科技女性榜:蓝港互动廖明香、百度李莹等上榜
  10. Java---读取.properties配置文件空指针异常
  11. 将字符转换成带有圆圈的字符
  12. 【知乎热议】如何看待Momenta研发总监任少卿去了蔚来汽车?
  13. 如果你毕业想进央企, 那就选这些大学, 性价比很高
  14. matlab xticklabel 旋转,在Matlab中,如何实现xticklabel的旋转?转
  15. 重构分析21: 被拒绝的遗赠(Refused Bequest)
  16. 简述关于ASP.NET MVC与.NET CORE 的区别
  17. 201771010112罗松《面向对象程序设计(java)》第十一周学习总结
  18. 程序员夏天穿格子衫,那么冬天穿什么?
  19. [bzoj4453]cys就是要拿英魂!
  20. 单片机编程技术学习攻略

热门文章

  1. 中国名校计算机专业分析介绍
  2. 全球公认十大骨传导耳机排行榜,骨传导怎么选?骨传导对比评测
  3. java.net.UnknownHostException: iZm5e8xpme70yxqoa4zoydZ
  4. Linux自学之旅-基础命令(mount挂载FAT32文件系统U盘设备文件)
  5. Navicat Premium12 安装报错、解决办法
  6. 浅谈MEC移动边缘计算
  7. 天池大赛-用户在商场中的定位
  8. 关于电子标准机柜的“U”和“19英寸”
  9. 在eclipse中写java项目,简单使用hsqldb数据库--菜鸟教程
  10. LightGCN 代码解析