https://vjudge.net/problem/Gym-100712H

题意:

给出一个图,求添加一条边后最少的桥数量。

思路:

参考了ZSQ大神的题解http://blog.csdn.net/v5zsq/article/details/61922051

很明显的边—双连通的题目,首先缩点建新图。然后寻找树中的最大直径,这样就能将桥的数量减至最小。

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<vector>
  6. #include<queue>
  7. #include<cmath>
  8. #include<map>
  9. #include<stack>
  10. using namespace std;
  11.  
  12. const int maxn=+;
  13.  
  14. struct Edge
  15. {
  16. int to,next;
  17. bool flag;//标记是否是桥
  18. }edge[maxn*];
  19.  
  20. stack<int> S;
  21. int n,m;
  22. int head[maxn],tot;
  23. int low[maxn],dfn[maxn],belong[maxn];
  24. int index,top;
  25. int block;//边双连通块数
  26. bool instack[maxn];
  27. int bridge;//桥的数目
  28. int e[maxn][];
  29. int deep; //最长直径
  30. int pos; //最长直径端点
  31.  
  32. void addedge(int u,int v)
  33. {
  34. edge[tot].to=v,edge[tot].next=head[u],edge[tot].flag=;
  35. head[u]=tot++;
  36. }
  37.  
  38. void Tarjan(int u,int pre)
  39. {
  40. int v;
  41. low[u]=dfn[u]=++index;
  42. S.push(u);
  43. instack[u]=;
  44. for(int i=head[u];~i;i=edge[i].next)
  45. {
  46. v=edge[i].to;
  47. if(v==pre)continue;
  48. if(!dfn[v])
  49. {
  50. Tarjan(v,u);
  51. if(low[u]>low[v])low[u]=low[v];
  52. if(low[v]>dfn[u])
  53. {
  54. bridge++;
  55. edge[i].flag=;
  56. edge[i^].flag=;
  57. }
  58. }
  59. else if(instack[v]&&low[u]>dfn[v])
  60. low[u]=dfn[v];
  61. }
  62. if(low[u]==dfn[u])
  63. {
  64. block++;
  65. do
  66. {
  67. v=S.top(); S.pop();
  68. instack[v]=;
  69. belong[v]=block;
  70. }
  71. while(v!=u);
  72. }
  73. }
  74.  
  75. void init()
  76. {
  77. memset(dfn,,sizeof(dfn));
  78. index=block=top=bridge=tot=;
  79. memset(head,-,sizeof(head));
  80. }
  81.  
  82. //邻接表寻找树的直径
  83. void dfs(int u,int fa,int cnt)
  84. {
  85. if(cnt>deep) {deep=cnt;pos=u;}
  86. for(int i=head[u];~i;i=edge[i].next)
  87. {
  88. int v=edge[i].to;
  89. if(v!=fa) dfs(v,u,cnt+);
  90. }
  91. }
  92.  
  93. int main()
  94. {
  95. //freopen("D:\\input.txt","r",stdin);
  96. int T;
  97. scanf("%d",&T);
  98. while(T--)
  99. {
  100. scanf("%d%d",&n,&m);
  101. init();
  102. for(int i=;i<=m;i++)
  103. {
  104. scanf("%d%d",&e[i][],&e[i][]);
  105. addedge(e[i][],e[i][]);
  106. addedge(e[i][],e[i][]);
  107. }
  108. Tarjan(,);
  109.  
  110. //缩点,重建图
  111. tot=;
  112. memset(head,-,sizeof(head));
  113. int ans=;
  114. for(int i=;i<=m;i++)
  115. {
  116. int u=belong[e[i][]], v=belong[e[i][]];
  117. if(u!=v)
  118. {
  119. ans++;
  120. addedge(u,v);
  121. addedge(v,u);
  122. }
  123. }
  124.  
  125. deep=;
  126. dfs(,,);
  127. deep=;
  128. dfs(pos,pos,);
  129. printf("%d\n",ans-deep);
  130. }
  131. return ;
  132. }

Gym - 100712H Bridges(边—双连通分量)的更多相关文章

  1. zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

    Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...

  2. hdoj 4738 Caocao's Bridges【双连通分量求桥】

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  3. Gym - 100676H H. Capital City (边双连通分量缩点+树的直径)

    https://vjudge.net/problem/Gym-100676H 题意: 给出一个n个城市,城市之间有距离为w的边,现在要选一个中心城市,使得该城市到其余城市的最大距离最短.如果有一些城市 ...

  4. HDU 4738 双连通分量 Caocao's Bridges

    求权值最小的桥,考虑几种特殊情况: 图本身不连通,那么就不用派人去了 图的边双连通分量只有一个,答案是-1 桥的最小权值是0,但是也要派一个人过去 #include <iostream> ...

  5. POJ3352 Road Construction(边双连通分量)

                                                                                                         ...

  6. POJ3352 Road Construction (双连通分量)

    Road Construction Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Sub ...

  7. 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 ...

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

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

  9. POJ3352 Road Construction 双连通分量+缩点

    Road Construction Description It's almost summer time, and that means that it's almost summer constr ...

随机推荐

  1. 为golang程序使用pprof远程查看httpserver运行堆栈,cpu耗时等信息

    pprof是个神马玩意儿? pprof - manual page for pprof (part of gperftools) 是gperftools工具的一部分 gperftools又是啥? Th ...

  2. SKBUFFER详解

    纯属转载,不敢侵犯别人产权!! 一. SKB_BUFF的基本概念1. 一个完整的skb buff组成(1) struct sk_buff--用于维护socket buffer状态和描述信息(2) he ...

  3. sVIrt概述

    sVirt概述 前面已经对seLInux的基本原理做了分析,seLinux主要就是基于主体和客体的安全上下文,进行访问决策.那么安全上下文是不是又可以理解为一个标签呢? 基于以上seLInux的特性, ...

  4. Python 开发中高级技巧

    列表推导式 >>> chars = [ c for c in 'python' ] >>> chars ['p', 'y', 't', 'h', 'o', 'n'] ...

  5. Git Extension工具安装及使用

    以下界面所示的三个工具,如果没安装过,则勾上让其安装.MsysGit为Git的Windows版本,必须要安装:Kdiff为对比/合并工具,可选安装,可以换为使用其它的相关工具:最后一个Windows ...

  6. myeclipse自动设置类和方法的注释(快捷键)

    类的注释 第一步:找到Window→Preferences→Java→Code Style→Code Templates→Comments→Types 第二步:编辑Pattern,我一般用的模板 /* ...

  7. volatile变量,java内存模型

    volatile变量提供了最轻量级的同步机制,当一个变量加上volatile修饰时,会具有一下两个特性 https://blog.csdn.net/u011277123/article/details ...

  8. Spark SQL中UDF和UDAF

    转载自:https://blog.csdn.net/u012297062/article/details/52227909 UDF: User Defined Function,用户自定义的函数,函数 ...

  9. 更新表中数据可以使用join

    1.在修改数据库的时候,每写完一条SQL语句都要加上一个分号,这样每句之间是有依赖关系的,上面执行不成功不会执行下面的语句. 2.在更新数据库中数据时可以使用join. 例如: update res ...

  10. webService 总结

    Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...