今天洛谷疯狂给我推送tarjan的题(它好像发现了我最近学tarjan),我正好做一做试一试(顺便练一练快读和宏定义)。

其实找割点的tarjan和算强连通分量的tarjan不一样,找割点的判定条件比较狗。

首先选定一个根节点,从该根节点开始遍历整个图(使用DFS)。

对于根节点,判断是不是割点很简单——计算其子树数量,如果有2棵即以上的子树,就是割点。因为如果去掉这个点,这两棵子树就不能互相到达。

对于非根节点,判断是不是割点就有些麻烦了。我们维护两个数组dfn[]和low[],dfn[u]表示顶点u第几个被(首次)访问,low[u]表示顶点u及其子树中的点,通过非父子边(回边),能够回溯到的最早的点(dfn最小)的dfn值(但不能通过连接u与其父节点的边)。对于边(u, v),如果low[v]>=dfn[u],此时u就是割点。

但这里也出现一个问题:怎么计算low[u]。

假设当前顶点为u,则默认low[u]=dfn[u],即最早只能回溯到自身。

有一条边(u, v),如果v未访问过,继续DFS,DFS完之后,low[u]=min(low[u], low[v]);

如果v访问过(且u不是v的父亲),就不需要继续DFS了,一定有dfn[v]<dfn[u],low[u]=min(low[u], dfn[v])。

洛谷模板代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define duke(i,a,n) for(int i = a;i <= n;i++)
  5. #define lv(i,a,n) for(int i = a;i >= n;i--)
  6. using namespace std;
  7. int dfn[],low[],lst[],len = ;
  8. int ans = ,top = ,n,m,tot = ,cut[];
  9. bool vis[];
  10. template <class T>
  11. void read(T &x)
  12. {
  13. char c;
  14. bool op = ;
  15. while(c = getchar(),c < '' || c > '')
  16. if(c == '-') op = ;
  17. x = c - '';
  18. while(c = getchar(),c >= '' && c <= '')
  19. {
  20. x = x * + c - '';
  21. }
  22. if(op == )
  23. x = -x;
  24. }
  25. struct node{
  26. int l,r,nxt;
  27. }a[];
  28. void add(int x,int y)
  29. {
  30. a[++len].l = x;
  31. a[len].r = y;
  32. a[len].nxt = lst[x];
  33. lst[x] = len;
  34. }
  35. void tarjan(int x,int fa)
  36. {
  37. int child = ;
  38. dfn[x] = low[x] = ++tot;
  39. // stc[++top] = x;
  40. // vis[x] = 1;
  41. for(int k = lst[x];k;k = a[k].nxt)
  42. {
  43. int y = a[k].r;
  44. if(!dfn[y])
  45. {
  46. tarjan(y,fa);
  47. low[x] = min(low[x],low[y]);
  48. if (low[y] >= dfn[x] && fa != x) cut[x]=true;
  49. if(x == fa)
  50. child++;
  51. }
  52. // else if(vis[y])
  53. {
  54. low[x] = min(low[x],dfn[y]);
  55. }
  56. }
  57. if(x == fa && child >= )
  58. cut[x] = true;
  59. }
  60. int main()
  61. {
  62. memset(cut,false,sizeof(cut));
  63. read(n); read(m);
  64. duke(i,,m)
  65. {
  66. int x,y;
  67. read(x);read(y);
  68. add(x,y);
  69. add(y,x);
  70. }
  71. duke(i,,n)
  72. {
  73. if(dfn[i] == )
  74. {
  75. tarjan(i,i);
  76. }
  77. }
  78. int num = ;
  79. duke(i,,n)
  80. {
  81. if(cut[i])
  82. num++;
  83. }
  84. printf("%d\n",num);
  85. duke(i,,n)
  86. {
  87. if(cut[i])
  88. printf("%d ",i);
  89. }
  90. return ;
  91. }
  92. /*
  93. 6 7
  94. 1 2
  95. 1 3
  96. 1 4
  97. 2 5
  98. 3 5
  99. 4 5
  100. 5 6
  101. */

tarjan用法——割点的更多相关文章

  1. UESTC 900 方老师炸弹 --Tarjan求割点及删点后连通分量数

    Tarjan算法. 1.若u为根,且度大于1,则为割点 2.若u不为根,如果low[v]>=dfn[u],则u为割点(出现重边时可能导致等号,要判重边) 3.若low[v]>dfn[u], ...

  2. POJ 1144 Network(Tarjan求割点)

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12707   Accepted: 5835 Descript ...

  3. poj 1523 SPF(tarjan求割点)

    本文出自   http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...

  4. poj_1144Network(tarjan求割点)

    poj_1144Network(tarjan求割点) 标签: tarjan 割点割边模板 题目链接 Network Time Limit: 1000MS Memory Limit: 10000K To ...

  5. 洛谷P3388 【模板】割点(割顶)(tarjan求割点)

    题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...

  6. 图论分支-Tarjan初步-割点和割边

    所谓割点(顶)割边,我们引进一个概念 割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图. 割边(桥):删掉一条边后,图必然会分裂成两个或两个以上的子图,又称桥. 这样大家就 ...

  7. [POJ1144][BZOJ2730]tarjan求割点

    求割点 一种显然的n^2做法: 枚举每个点,去掉该点连出的边,然后判断整个图是否联通 用tarjan求割点: 分情况讨论 如果是root的话,其为割点当且仅当下方有两棵及以上的子树 其他情况 设当前节 ...

  8. poj1144 tarjan求割点

    poj1144 tarjan求割点 额,算法没什么好说的,只是这道题的读入非常恶心. 注意,当前点x是否是割点,与low[x]无关,只和low[son]和dfn[x]有关. 还有,默代码的时候记住分目 ...

  9. tarjan求割点割边的思考

    这个文章的思路是按照这里来的.这里讨论的都是无向图.应该有向图也差不多. 1.如何求割点 首先来看求割点.割点必须满足去掉其以后,图被分割.tarjan算法考虑了两个: 根节点如果有两颗及以上子树,它 ...

随机推荐

  1. Java笔记整理列表

    整理Java相关知识点. 2018-11-20 1:Java入门学习 2:Java进阶

  2. mt_rand()和rand()两者的区别

    在随机读取中使用了mt_rand(),而不适用rand(),他们两者的区别: mt_rand()是更好地随机数生成器,因为它跟rand()相比播下了一个更好地随机数种子:而且性能上比rand()快4倍 ...

  3. Quartz.NET 定时任务使用

    class Program { static void Main(string[] args) { StartJob(); Console.ReadKey(); } static void Start ...

  4. C lstat major MAJOR 获得设备号

    #cat lstat.c #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #inc ...

  5. 293. [NOI2000] 单词查找树——COGS

    293. [NOI2000] 单词查找树 ★★   输入文件:trie.in   输出文件:trie.out   简单对比时间限制:1 s   内存限制:128 MB 在进行文法分析的时候,通常需要检 ...

  6. 小白神器 - 一篇博客学会HTML

    小白神器 - 一篇博客学会HTML 一. 简介 1. HTML 定义 htyper text markup language  即超文本标记语言. 超文本: 就是指页面内可以包含图片.链接,甚至音乐. ...

  7. 解析特殊格式的xml到map

    由于项目特殊,需要解析的xml文档样式特别,所以自己写了一个解析特殊xml的方法 先提供xml样式 <?xml version="1.0" encoding="UT ...

  8. openstack部署工具简介

    个人使用方面DevStack无疑,在可预见的未来时间内,DevStack仍将是众多开发者们的首选安装方式或工具.该方式主要是通过配置参数,执行shell脚本来安装一个OpenStack的开发环境.Gi ...

  9. Square words(codevs 3301)

    题目描述 Description 定义square words为: 1.长度为偶数. 2.前一半等于后一半. 比如abcabc和aaaa都是square words,但是abcabcab和aaaaa都 ...

  10. 开启mysql远程连接

    mysql默认只允许本地连接,也就是说,在安装完mysql后会存在两个root账户,他们的host分别是localhost和127.0.0.1 use mysql; update user set h ...