题意抽象后为:
给定一个无向图

问添加一条边的情况下最少能有多少个桥。

桥的定义:删除该边后原图变为多个连通块。

数据规模:点数N(2<=N<=200000),边数M(1<=M<=1000000)

缩点之后求一下树的直径就好了,最优加边方案显然为连接直径的头尾。

AC代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #define rep(i,a,b) for(int i=a;i<=b;++i)
  5. using namespace std;
  6. const int MAXV=;
  7. const int MAXE=;
  8. int DFN[MAXV],low[MAXV],par[MAXV],label[MAXV];
  9. int pointer[MAXV];
  10. int tot,cnt,m,n,Bcnt,ans;
  11. vector<int> graph[MAXV];
  12. int dep[MAXV];
  13. struct Edge
  14. {
  15. int to,next;
  16. bool vis;
  17. Edge() {}
  18. Edge(int b,int nxt,int flag) {to=b,next=nxt,vis=flag;}
  19. }edge[MAXE];
  20. inline void addedge(int a,int b)
  21. {
  22. edge[tot]=Edge(b,pointer[a],);
  23. pointer[a]=tot++;
  24. edge[tot]=Edge(a,pointer[b],);
  25. pointer[b]=tot++;
  26. }
  27. void init()
  28. {
  29. tot=;
  30. cnt=;Bcnt=;
  31. memset(pointer,-,sizeof(pointer));
  32. memset(label,,sizeof(label));
  33. memset(DFN,,sizeof(DFN));
  34. rep(i,,n)
  35. {
  36. graph[i].clear();
  37. }
  38. }
  39. void tarjan(int u)
  40. {
  41. DFN[u]=low[u]=++cnt;
  42. for(int j=pointer[u];j!=-;j=edge[j].next)
  43. {
  44. int v=edge[j].to;
  45. if(edge[j].vis) continue;
  46. edge[j].vis=edge[j^].vis=;
  47. if(!DFN[v])
  48. {
  49. par[v]=j;
  50. tarjan(v);
  51. if(low[v]<low[u]) low[u]=low[v];
  52. }
  53. else if(low[u]>DFN[v]) low[u]=DFN[v];
  54. }
  55. }
  56. void part(int u)
  57. {
  58. label[u]=Bcnt;
  59. for(int j=pointer[u];j!=-;j=edge[j].next)
  60. {
  61. int v=edge[j].to;
  62. if(!label[v]&&edge[j].vis) part(v);
  63. }
  64. }
  65. void bfs(int s)
  66. {
  67. rep(i,,Bcnt) dep[i]=-;
  68. queue<int > q;
  69. dep[s]=;
  70. q.push(s);
  71. while(!q.empty())
  72. {
  73. int u=q.front();q.pop();
  74. for(int j=;j<graph[u].size();++j)
  75. {
  76. int v=graph[u][j];
  77. if(dep[v]==-)
  78. {
  79. dep[v]=dep[u]+;
  80. q.push(v);
  81. }
  82. }
  83. }
  84. }
  85. int diameter()
  86. {
  87. bfs();
  88. int ma=,tag;
  89. rep(i,,Bcnt)
  90. {
  91. if(dep[i]>ma)
  92. {
  93. tag=i;
  94. ma=dep[i];
  95. }
  96. }
  97. bfs(tag);
  98. ma=;
  99. rep(i,,Bcnt)
  100. {
  101. if(dep[i]>ma)
  102. {
  103. tag=i;
  104. ma=dep[i];
  105. }
  106. }
  107. return ma;
  108. }
  109. int main()
  110. {
  111. //freopen("in.txt","r",stdin);
  112. while(scanf("%d%d",&n,&m)==&&(n+m))
  113. {
  114. init();
  115. int u,v;
  116. rep(i,,m)
  117. {
  118. scanf("%d%d",&u,&v);
  119. addedge(u,v);
  120. }
  121. tarjan();
  122. int tmp;
  123. rep(i,,n)
  124. {
  125. tmp=par[i]^;
  126. u=edge[tmp].to;
  127. if(low[i]>DFN[u])
  128. {
  129. edge[tmp].vis=;
  130. edge[tmp^].vis=;
  131. }
  132. }
  133. Bcnt=;
  134. rep(i,,n)
  135. {
  136. if(!label[i])
  137. {
  138. Bcnt++;
  139. part(i);
  140. }
  141. }
  142. rep(i,,n)
  143. {
  144. if(!edge[par[i]].vis)
  145. {
  146. tmp=par[i]^;
  147. u=edge[tmp].to;
  148. graph[label[u]].push_back(label[i]);
  149. graph[label[i]].push_back(label[u]);
  150. }
  151. }
  152. printf("%d\n",Bcnt--diameter());
  153. }
  154. return ;
  155. }

hdu4612 Warm up 缩点+树的直径的更多相关文章

  1. HDU4612:Warm up(缩点+树的直径)

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

  2. HDU4612 Warm up 边双(重边)缩点+树的直径

    题意:一个连通无向图,问你增加一条边后,让原图桥边最少 分析:先边双缩点,因为连通,所以消环变树,每一个树边都是桥,现在让你增加一条边,让桥变少(即形成环) 所以我们选择一条树上最长的路径,连接两端, ...

  3. hdu 4612 Warm up 有重边缩点+树的直径

    题目链接 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tot ...

  4. hdu4612(双连通缩点+树的直径)

    传送门:Warm up 题意:询问如何加一条边,使得剩下的桥的数目最少,输出数目. 分析:tarjan缩点后,重新建图得到一棵树,树上所有边都为桥,那么找出树的直径两个端点连上,必定减少的桥数量最多, ...

  5. hdu-4612(无向图缩点+树的直径)

    题意:给你n个点和m条边的无向图,问你如果多加一条边的话,那么这个图最少的桥是什么 解题思路:无向图缩点和树的直径,用并查集缩点: #include<iostream> #include& ...

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

    <题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...

  7. F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解

    题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...

  8. codeforces GYM 100114 J. Computer Network 无相图缩点+树的直径

    题目链接: http://codeforces.com/gym/100114 Description The computer network of “Plunder & Flee Inc.” ...

  9. 【HDU 4612 Warm up】BCC 树的直径

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数 ...

随机推荐

  1. HTTP长连接、短连接究竟是什么?

    1. HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议. IP协议主要解决网络路由和寻址 ...

  2. 2的n次方用c语言怎么表示

    C语言有函数,需要头文件#include <math.h>用pow(2,n)就可以了! double result = pow(2,n);

  3. Python-图片文字识别

    百度AI接口(手写文字识别):https://ai.baidu.com/docs#/OCR-API/9ef46660 实现效果: 步骤一:接入接口 进入上述网站申请账号,然后运行相关代码,获取 acc ...

  4. loj2353. 「NOI2007」 货币兑换

    loj2353. 「NOI2007」 货币兑换 链接 https://loj.ac/problem/2353 思路 题目不重要,重要的是最后一句话 提示 输入文件可能很大,请采用快速的读入方式. 必然 ...

  5. spring boot2+jpa+thymeleaf增删改查例子

    参考这遍文章做了一个例子,稍微不同之处,原文是spring boot.mysql,这里改成了spring boot 2.Oracle. 一.pom.xml引入相关模块web.jpa.thymeleaf ...

  6. centos7安装bbr

    centos7安装bbr 安装 sudo wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.s ...

  7. SAP Hybris电子商务最新功能

    SAP Hybris电子商务最新功能   SAP Hybris 电子商务6.0中国加速器是专为中国市场设计的电子商务平台,可满足企业在全渠道销售和订单履行方面的所有需求.新版的中国加速器基于SAP H ...

  8. Apache web服务器(LAMP架构)

    Apache web服务器(LAMP架构) apache介绍 1).世界上使用率最高的网站服务器,最高时可达70%:官方网站:apache.org 2).http 超文本协议 HTML 超文本标记语言 ...

  9. 几种优化方法的整理(SGD,Adagrad,Adadelta,Adam)

    参考自: https://zhuanlan.zhihu.com/p/22252270 常见的优化方法有如下几种:SGD,Adagrad,Adadelta,Adam,Adamax,Nadam 1. SG ...

  10. SQL LITE安装

    SQLite是一款轻型的嵌入式关系数据库,轻量级,效率高,操作起来也特别方便我们今天来讲解一下SQLite的安装和一些基本操作SQLite下载我是64位机,下载下面的两个解压就好添加path环境变量, ...