问加一条边,最少可以剩下几个桥。

先双连通分量缩点,形成一颗树,然后求树的直径,就是减少的桥。

本题要处理重边的情况。

如果本来就两条重边,不能算是桥。

还会爆栈,只能C++交,手动加栈了

别人都是用的双连通分量,我直接无向图改成有向图搞得强连通水过。

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include <iostream>
  3. #include <vector>
  4. #include <queue>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <stack>
  9.  
  10. using namespace std;
  11. const int maxn = ;
  12. bool vis[];
  13. struct edge
  14. {
  15. int v,next;
  16. edge()
  17. {
  18. next = -;
  19. }
  20. }edges[maxn*-];
  21. struct ed
  22. {
  23. int u,v;
  24. }e[maxn*-];
  25. int dfn[],low[],belong[];
  26. bool inst[];
  27. int g[maxn];
  28. vector<int>ng[maxn];
  29.  
  30. stack<int>st;
  31. int bcnt,cnt,time;
  32.  
  33. void init(int n)
  34. {
  35. int i;
  36. for(i =;i <= n;i++)
  37. g[i] = -;
  38. time = ;bcnt = cnt = ;
  39. return ;
  40. }
  41. void addedge(int u,int v,int val)
  42. {
  43. struct edge o;
  44. edges[cnt].v = v;
  45. edges[cnt].next = g[u];
  46. g[u] = cnt;
  47. cnt++;
  48.  
  49. return ;
  50. }
  51. void tarjan(int i)
  52. {
  53. int j;
  54. dfn[i] = low[i] = ++time;
  55. inst[i] = ;
  56. st.push(i);
  57.  
  58. for(j = g[i];j != -;j = edges[j].next)
  59. {
  60. if(vis[j]) continue;
  61. vis[j] = vis[j^] = ;
  62. int v;
  63. v = edges[j].v;
  64. if(!dfn[v])
  65. {
  66. tarjan(v);
  67. low[i] = min(low[i],low[v]);
  68. }
  69. else if(inst[v])
  70. low[i] = min(low[i],dfn[v]);
  71. }
  72. int k;
  73. if(dfn[i] == low[i])
  74. {
  75.  
  76. bcnt++;
  77. do
  78. {
  79. k = st.top();
  80. st.pop();
  81. inst[k] = ;
  82. belong[k] = bcnt;
  83.  
  84. }
  85. while(k != i);
  86. }
  87.  
  88. }
  89. void tarjans(int n)
  90. {
  91. int i;
  92. bcnt = time = ;
  93. while(!st.empty())st.pop();
  94. memset(dfn,,sizeof(dfn));
  95.  
  96. memset(inst,,sizeof(inst));
  97. memset(belong,,sizeof(belong));
  98. for(i = ;i <= n;i++)
  99. if(!dfn[i])tarjan(i);
  100. }
  101. struct node
  102. {
  103. int s,point;
  104. };
  105.  
  106. struct node bfs(int s)
  107. {
  108. int i;
  109. for(i = ;i <= bcnt;i++)
  110. vis[i] = ;
  111. queue <struct node>q;
  112. struct node p;
  113. p.s = ;p.point = s;
  114. q.push(p);
  115. vis[s] = ;
  116. struct node max;
  117. max.s = ;
  118.  
  119. while(!q.empty())
  120. {
  121. struct node now,temp;
  122. now = q.front();
  123. q.pop();
  124.  
  125. for(i = ;i < ng[now.point].size();i++)
  126. {
  127. int v = ng[now.point][i];
  128. temp.s = now.s+;
  129. temp.point = v;
  130. if(!vis[v])
  131. {
  132. vis[v] = ;
  133. // cout<<v<<"***"<<endl;
  134.  
  135. if(max.s < temp.s)
  136. max = temp;
  137. q.push(temp);
  138. }
  139. }
  140. }
  141. return max;
  142. }
  143. int main()
  144. {
  145. int n,m;
  146. //freopen("in.txt","r",stdin);
  147. while(scanf("%d %d",&n,&m)&&(n||m))
  148. {
  149. int a,b,i;
  150. init(n);
  151. memset(vis,,sizeof(vis));
  152. for(i = ;i < m;i++)
  153. {
  154. scanf("%d %d",&e[i].u,&e[i].v);
  155. addedge(e[i].u,e[i].v,);
  156. addedge(e[i].v,e[i].u,);
  157. }
  158. tarjans(n);
  159.  
  160. for(i = ;i <= n;i++)
  161. {
  162. ng[i].clear();
  163. }
  164.  
  165. for(i = ;i < m;i++)
  166. {
  167. if(belong[e[i].u] == belong[e[i].v])
  168. continue;
  169. ng[belong[e[i].u]].push_back(belong[e[i].v]);
  170. ng[belong[e[i].v]].push_back(belong[e[i].u]);
  171. }
  172. struct node max;
  173. max = bfs();
  174. max = bfs(max.point);
  175. printf("%d\n",bcnt-max.s-);
  176. }
  177. return ;
  178. }

4612 warm up tarjan+bfs求树的直径(重边的强连通通分量)忘了写了,今天总结想起来了。的更多相关文章

  1. HDU4612+Tarjan缩点+BFS求树的直径

    tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...

  2. [USACO2004][poj1985]Cow Marathon(2次bfs求树的直径)

    http://poj.org/problem?id=1985 题意:就是给你一颗树,求树的直径(即问哪两点之间的距离最长) 分析: 1.树形dp:只要考虑根节点和子节点的关系就可以了 2.两次bfs: ...

  3. 牛客小白月赛6C-桃花(DFS/BFS求树的直径)

    链接:https://www.nowcoder.com/acm/contest/136/C 来源:牛客网 桃花 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言 ...

  4. 两次bfs求树的直径的正确性

    结论:离树上任意点\(u\)最远的点一定是这颗树直径的一个端点. 证明: 若点\(u\)在树的直径上,设它与直径两个端点\(x,y\)的距离分别为\(S1\).\(S2\),若距离其最远的点\(v\) ...

  5. hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】

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

  6. (求树的直径)Warm up -- HDU -- 4612

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4612 给一个无向图, 加上一条边后,求桥至少有几个: 那我们加的那条边的两个顶点u,v:一定是u,v之 ...

  7. HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边

    Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...

  8. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  9. poj2631 求树的直径裸题

    题目链接:http://poj.org/problem?id=2631 题意:给出一棵树的两边结点以及权重,就这条路上的最长路. 思路:求实求树的直径. 这里给出树的直径的证明: 主要是利用了反证法: ...

随机推荐

  1. Altium Designer Summer 09创建半圆焊盘方法

    关于异形焊盘的创建,可参看下面的半圆PAD的制作:1.新建一个PCB文件,然后在里面画一个半圆的Arc,即Place放置(P)>Arc,并且要将其开口处 封闭,即可用Place   放置(P)& ...

  2. linux gcc loudong

    五事九思 (大连Linux主机维护) 大连linux维护qq群:287800525 首页 日志 相册 音乐 收藏 博友 关于我     日志       spcark_0.0.3_i386.src.t ...

  3. POJ 1759

    Garland Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1236   Accepted: 547 Descriptio ...

  4. POJ 2021

    #include <iostream> #include <string> #include <algorithm> #define MAXN 105 using ...

  5. HDU5569/BestCoder Round #63 (div.2) C.matrix DP

    matrix Problem Description Given a matrix with n rows and m columns ( n+m is an odd number ), at fir ...

  6. android真机自动化测试

    appium执行用例时报错问题: 问题解析: 一般该种情况都是因为来连接了多个设备,验证办法:cmd->执行adb devices  看结果是否是多个devices ,如果是这个问题,停掉多余设 ...

  7. 自动化 测试框架部署(python3+selenium2)

    安装Python 从https://www.python.org/downloads/下载最新版本的Python3,请注意,是3: 需要将Python的安装目录和安装目录下的Scripts文件夹添加到 ...

  8. SSH连接不上Linux的解决方法

    SSH连接不上Linux的解决方法: 连续弄了几次,今天早上终于把SSH连接虚拟机连接不通的问题解决了. 先简单说下概要: 主机装的是XP系统,虚拟机用的是red hat Linux. 我用的是nat ...

  9. Spark源码分析(三)-TaskScheduler创建

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3879151.html 在SparkContext创建过程中会调用createTaskScheduler函 ...

  10. C++函数默认参数

    C++中允许为函数提供默认参数,又名缺省参数. 使用默认参数时的注意事项: ① 有函数声明(原型)时,默认参数可以放在函数声明或者定义中,但只能放在二者之一 double sqrt(double f ...