这个题目网上有很多答案,代码也很像,不排除我的。大家的思路应该都是taijan求出割边,然后找两个点的LCA(最近公共祖先),这两个点和LCA以及其他点构成了一个环,我们判断这个环上的割边有几条,我们的答案就少几个。

  有人问,这个题重边怎么办呢,重边肯定不是桥啊。额……对于这个我只能说,这个题的原始图应该是没有重边的,后来加的边可能会有重边,不过不影响我们的判断,因为我们通过标记点的方式去判的。(这个题还是应该说明一下啊,题目有点问题……)。

  其次,这个题的好玩之处来了,网上人分享的代码,居然过不了一组很简单的样例(如下),(现在大多人可能已经修正了),其实这个原因我应该是找到了,那就是dfn(出生日期)和deep(深搜的层数)的使用错误,当你使用deep的时候交换两者的值是没错的,因为我们总能让他们调整到一层上,然后他们的LCA也一定在一层上了,使用fa数组可以追溯到他们的LCA。然而如果是用dfn交换两者的值就是错误的了,因为即使你调整了他们的值满足一定的大小关系,他们也不一定在一层上,很有可能追溯到了环的外面,所以在追溯的时候很可能会多减上几条边。也就是出现了下面的样例,答案是1,有人输出了0;

  其实这个地方我一直有一个疑惑,那就是使用dfn判断的时候,最后的时候居然会出现二者不相等的情况,这与深搜的性质相违背,到现在也没找到一个样例可以说明他是正确的,我确实感觉到当判断完前两个循环的时候dfn【u】就是他们的LCA了,这个疑惑我先放到这里,便于以后解答,在以后我会主要选择记录深度的方法去做,比较好理解,比较保险(就如我下面代码里的方法)

  附:这个题还有一个解决方法,就是求双连通分量,通过判断两点是否在一个分量里判断两点之间的边是否为桥,然后再合并这两个点。求连通分量的办法一种是并查集,在判断的时候合并到一个集合里,一种是栈的储存方式,id数组,与有向图求强连通分量的方法一致。注意无向图的双连通分量不是指能否相互到达,而是指这个分量里面不含桥,所以当两个点不在一个集合中的时候,这条边一定就是桥。

6 5
1 2
2 3
2 4
3 5
4 6
1
5 6

答案:1

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. #define maxn 100010
  6. int head[maxn],dfn[maxn],low[maxn],fa[maxn],deep[maxn];
  7. int all,tot,bridge[maxn],brinum;
  8. struct Edge
  9. {
  10. int to,nxt;
  11. } edge[*maxn];
  12. void addadge(int a,int b)
  13. {
  14. edge[tot].to = b;
  15. edge[tot].nxt = head[a];
  16. head[a] = tot++;
  17. }
  18. void dfs(int u,int pa)
  19. {
  20. low[u] = dfn[u] = ++all;
  21. deep[u] = deep[pa] + ;
  22. for(int i = head[u]; i != -; i = edge[i].nxt)
  23. {
  24. int v = edge[i].to;
  25. if(!dfn[v])
  26. {
  27. fa[v] = u;
  28. dfs(v,u);
  29. low[u] = min(low[u],low[v]);
  30. if(low[v] > dfn[u])
  31. {
  32. bridge[v] = ;
  33. brinum++;
  34. }
  35. }
  36. else if(v != pa) low[u] = min(low[u],dfn[v]);
  37. }
  38. }
  39. void lca(int a,int b)
  40. {
  41. while(deep[a] > deep[b])
  42. {
  43. if(bridge[a])
  44. {
  45. bridge[a] = ;
  46. brinum--;
  47. }
  48. a = fa[a];
  49. }
  50. while(deep[b] > deep[a])
  51. {
  52. if(bridge[b])
  53. {
  54. bridge[b] = ;
  55. brinum--;
  56. }
  57. b = fa[b];
  58. }
  59. while(a != b)
  60. {
  61. if(bridge[a])
  62. {
  63. bridge[a] = ;
  64. brinum--;
  65. }
  66. if(bridge[b])
  67. {
  68. bridge[b] = ;
  69. brinum--;
  70. }
  71. a = fa[a];
  72. b = fa[b];
  73. }
  74. }
  75. int main()
  76. {
  77. int n,m,q,a,b,ca = ;
  78. while(~scanf("%d%d",&n,&m))
  79. {
  80. if(!n && !m) break;
  81. for(int i = ; i <= n; i++)
  82. {
  83. head[i] = -;
  84. dfn[i] = ;
  85. low[i] = ;
  86. fa[i] = i;
  87. deep[i] = ;
  88. bridge[i] = ;
  89. }
  90. tot = ;
  91. all = ;
  92. brinum = ;
  93. for(int i = ; i < m; i++)
  94. {
  95. scanf("%d%d",&a,&b);
  96. addadge(a,b);
  97. addadge(b,a);
  98. }
  99. dfs(,);
  100. scanf("%d",&q);
  101. printf("Case %d:\n",++ca);
  102. while(q--)
  103. {
  104. scanf("%d%d",&a,&b);
  105. lca(a,b);
  106. printf("%d\n",brinum);
  107. }
  108. puts("");
  109. }
  110. return ;
  111. }

POJ 1236 Network of Schools(tarjan算法 + LCA)的更多相关文章

  1. Poj 1236 Network of Schools (Tarjan)

    题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个 ...

  2. POJ 1236 Network of Schools (Tarjan + 缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12240   Accepted: 48 ...

  3. POJ 1236 Network of Schools Tarjan缩点

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22729   Accepted: 89 ...

  4. POJ 1236 Network of Schools(强连通 Tarjan+缩点)

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  5. POJ 1236 Network of Schools(强连通分量)

    POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...

  6. [tarjan] poj 1236 Network of Schools

    主题链接: http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K To ...

  7. poj 1236 Network of Schools(连通图入度,出度为0)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  8. poj 1236 Network of Schools(又是强连通分量+缩点)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  9. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

  10. poj 1236 Network of Schools(tarjan+缩点)

    Network of Schools Description A number of schools are connected to a computer network. Agreements h ...

随机推荐

  1. php 备份数据库

    <?php    header("Content-type:text/html;charset=utf-8");    //配置信息  $cfg_dbhost = 'loca ...

  2. 使用solrj查询数据(java代码)

    实体类Student,添加Field注解 package com.cs.solr.entity; import org.apache.solr.client.solrj.beans.Field; pu ...

  3. MySQL-MHA高可用方案

    http://files.cnblogs.com/jimingsong/mha-mysql.pdf 此方案为一号店MySQL MHA高可用方案.备注.

  4. ( ̄▽ ̄") 没钱了

    ( ̄▽ ̄") 没钱了 TimeLimit: 1000ms  MenoryLimit:65536KB 64-bit integer IO format:%lld Problem Descrip ...

  5. 斯坦福大学公开课:iOS 7应用开发 笔记

    2015-07-06 第一讲   课务.iOS概述 -------------------------------------------------- 开始学习斯坦福大学公开课:iOS 7应用开发留 ...

  6. Adobe flash CC 汉化破解方法

    转载整理自:http://www.sdifenzhou.com/flashprofessionalcc.html 断网,解压下载的破解dmg文件得到这些文件 第一步,解压安装包,安装,并打开,不要输入 ...

  7. Xcode调试之查看变量

    从其他开发语言转行进军IOS开发的小伙伴可能会有这样一件苦恼的事情,调试程序时如何查看变量值?我并不喜欢每次都要通过打印去查看变量的值,也不喜欢通过光标悬浮到变量上来显示变量的值,如果要查看变量的属性 ...

  8. InnoDB表要建议用自增列做主键

    InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子节点(leaf pages of the tre ...

  9. Valgrind: memcheck of memleak/mem-uninitialization; massif usage

    first install valgrind, its newest ver is 3.11, and stops updating since 2015/12. in centos, yum ins ...

  10. CCNET+MSBuild+SVN实时构建的优化总结

    本文不是介绍如何使用CCNET+MSBuild+SVN构建自动编译系统,相关的内容可以从很多地方获取,可以再园子里搜一下. 随着我们的SVN库日益壮大,容量达到10G,几十G 甚至更大时,我们发现自动 ...