题目大意:
给你一个无向图,问加一条边之后最少还剩下几座桥。
(注意重边处理)
 
分析:其实当我们把边双连通分量给求出来之后我们就能将连通块求出来,这样我们就可以重新构图。重新构造出来的图肯定是一颗树了,
那么问题就转化为求树的哪两个节点的距离最长。我们可以随便找一个点S开始BFS, BFS到这个点最远的那个点P,然后再从这个最远点P开始BFS,BFS到P最远的点E,  PE之间的距离就是这个图上最大的距离。
 
注:此题需要手动扩栈
  1. #pragma comment(linker, "/STACK:102400000,102400000")
  2. #include <iostream>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <queue>
  8. #include <cmath>
  9. #include <stack>
  10. #include <cstring>
  11. usingnamespace std;
  12. #define INF 0xfffffff
  13. #define maxn 200005
  14. #define min(a,b) (a<b?a:b)
  15. int m, n, Time, top, cnt;
  16. int blocks[maxn], dfn[maxn], low[maxn], Stacks[maxn], Father[maxn];
  17. int step[maxn];
  18. vector<vector<int> > G;
  19. vector<vector<int> > G2;
  20. void init()
  21. {
  22. memset(dfn, , sizeof(dfn));
  23. memset(low, , sizeof(low));
  24. memset(blocks, , sizeof(blocks));
  25. Time = top = cnt = ;
  26. G.clear();
  27. G.resize(n+);
  28.  
  29. G2.clear();
  30. G2.resize(n+);
  31. }
  32. void Tarjan(int u,int fa)
  33. {
  34. dfn[u] = low[u] = ++Time;
  35. Stacks[top ++] = u;
  36. Father[u] = fa;
  37. int len = G[u].size(), k = , v;
  38.  
  39. for(int i=; i<len; i++)
  40. {
  41. v = G[u][i];
  42.  
  43. if( !k && fa == v)
  44. {
  45. k ++;
  46. continue;
  47. }
  48.  
  49. if( !low[v] )
  50. {
  51. Tarjan(v, u);
  52. low[u] = min(low[u], low[v]);
  53. }
  54. else
  55. low[u] = min(low[u], dfn[v]);
  56. }
  57.  
  58. if(dfn[u] == low[u])
  59. {
  60. do
  61. {
  62. v = Stacks[--top];
  63. blocks[v] = cnt;
  64. }while(u != v);
  65. cnt ++;
  66. }
  67. }
  68. int BFS(int s,int flag)
  69. {
  70. int P, Pn;
  71. queue<int> Q;
  72. Q.push(s);
  73. memset(step, -, sizeof(step));
  74. step[s] = ;
  75. while( Q.size() )
  76. {
  77. P = Q.front();
  78. Q.pop();
  79.  
  80. int len = G2[P].size();
  81.  
  82. for(int i=; i<len; i++)
  83. {
  84. Pn = G2[P][i];
  85.  
  86. if( step[Pn] == -)
  87. {
  88. step[Pn] = step[P] + ;
  89. Q.push(Pn);
  90. }
  91. }
  92. }
  93.  
  94. if(flag == )
  95. return P;
  96. return step[P];
  97. }
  98. void solve()
  99. {
  100. int ans = , i;
  101. for(i=; i<=n; i++)
  102. {
  103. if(!low[i])
  104. Tarjan(i, i);
  105. }
  106.  
  107. for(i=; i<=n; i++)
  108. {
  109. int v = Father[i];
  110.  
  111. if(blocks[i] != blocks[v])
  112. { /**重新构图*/
  113. G2[blocks[i] ].push_back(blocks[v]);
  114. G2[blocks[v] ].push_back(blocks[i]);
  115. }
  116. }
  117.  
  118. int p = BFS(,);///以0为起点经行一次BFS返回最远距离的编号
  119.  
  120. ans = cnt - BFS(p, ) - ;///返回最远距离的长度
  121. printf("%d\n", ans);
  122.  
  123. }
  124.  
  125. int main()
  126. {
  127. while(scanf("%d %d",&n, &m), m+n)
  128. {
  129. init();
  130. while(m--)
  131. {
  132. int a, b;
  133. scanf("%d %d",&a, &b);
  134. G[a].push_back(b);
  135. G[b].push_back(a);
  136. }
  137. solve();
  138. }
  139. return0;
  140. }
  141. /*
  142. 5 4
  143. 1 2
  144. 1 3
  145. 1 4
  146. 2 5
  147. */

HDU 4612 Warm up(手动扩栈,求树上哪两个点的距离最远)的更多相关文章

  1. HDU 4612 Warm up tarjan缩环+求最长链

    Warm up Problem Description   N planets are connected by M bidirectional channels that allow instant ...

  2. HDU 4612 Warm up —— (缩点 + 求树的直径)

    题意:一个无向图,问建立一条新边以后桥的最小数量. 分析:缩点以后,找出新图的树的直径,将这两点连接即可. 但是题目有个note:两点之间可能有重边!而用普通的vector保存边的话,用v!=fa的话 ...

  3. Hdu 4612 Warm up (双连通分支+树的直径)

    题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...

  4. hdu 4612 Warm up 双连通+树形dp思想

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  5. HDU 4612 Warm up(2013多校2 1002 双连通分量)

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Su ...

  6. HDU 4612——Warm up——————【边双连通分量、树的直径】

    Warm up Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  7. hdu 4612 Warm up(无向图Tarjan+树的直径)

    题意:有N个点,M条边(有重边)的无向图,这样图中会可能有桥,问加一条边后,使桥最少,求该桥树. 思路:这个标准想法很好想到,缩点后,求出图中的桥的个数,然后重建图必为树,求出树的最长直径,在该直径的 ...

  8. HDU 4612 Warm up(Tarjan)

    果断对Tarjan不熟啊,Tarjan后缩点,求树上的最长路,注意重边的处理,借鉴宝哥的做法,开标记数组,标记自己的反向边. #pragma comment(linker, "/STACK: ...

  9. HDU 4612 Warm up(双连通分量缩点+求树的直径)

    思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...

随机推荐

  1. [iOS 开发] app无法访问本地相册,且不显示在设置 -隐私 - 照片中

    近几天在使用iOS8的Photos Framework访问本地相册时,app即不会弹出是否允许访问提示框,也无法显示在iPhone的设置-隐私-照片的访问列表中,代码如下: PHAuthorizati ...

  2. Spire.Barcode好用的条码生在组件

    由于项目的需要,今天在网上找了一下条码的组件,发现了一个简单易用的组件,使用简单,几句代码就搞定了.

  3. WPF TextSelection获取选中部分内容

    一.简单实例 //TextSelect继承自TextRange TextSelection selection = richTextBox.Selection; //1.获取选中内容 string r ...

  4. 关于一点coding.net与git配合在AndroidStudio/Idea上的使用笔记个的

    编写程序的我们经常需要对我们写的代码做版本控制,或者分支管理,具备类似功能的软件很多,诸如SVN,Git,CVS等等!但配置版本控制服务器(SVN server etc.)是繁琐的并且需要一定的成本! ...

  5. JAVA开发环境 - 环境变量及配置

    JDK是什么?JRE是什么? JRE(Java Runtime Environment):Java运行环境: JDK(Java Development Kit):Java开发工具包,里面已经包含JRE ...

  6. 谷歌地图实现车辆轨迹移动播放(google map api)

    开发技术:jquery,js baidu map api,json,ajax QQ1310651206 谷歌地图(google map api)实现车辆轨迹移动播放(google map api)

  7. javascript为目标位置div等设置高度

    应该是DOM的东西: document.getElementById("目标id").style.height = 多高(数值)+"px";

  8. 单元测试不是梦,Android+PowerMock系列(1) —— 在Eclipse里搭建测试环境

    单元测试不好搞阿,虽然从TDD角度出发,可测性强的代码很大程度上就代表着好的设计,但是有些情况也是没办法的,比如单例模式,比如Static方法,比如Final类,传统的Mock技术是没办法解决这些问题 ...

  9. BZOJ 1019 汉诺塔

    Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操 ...

  10. 巧用powerpoint制作符合期刊要求的复合图