题目链接:http://codeforces.com/problemset/problem/455/C

题意:

  给你一个森林,n个点,m条边。

  然后有t个操作。共有两种操作:

    (1)1 x:

      输出节点x所在树的直径。

    (2)2 x y:

      如果x,y不在同一棵树上的话,用一条边连接x,y所在的树,并且使得到的新树的直径尽可能小。

题解:

  首先对于初始状态,算出每一棵树的直径d[find(i)]。

  每次合并树的时候,因为要尽可能让新树直径变小,所以显然这条边要分别连接两棵树直径的“中点”。

  所以新树的直径 = max( d[x], d[y], ceil(d[x]/2)+ceil(d[y]/2)+1 )

  然后用并查集合并就好啦。

AC Code:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <vector>
  6. #define MAX_N 300005
  7.  
  8. using namespace std;
  9.  
  10. int n,m,t;
  11. int maxd;
  12. int op,ed;
  13. int d[MAX_N];
  14. int par[MAX_N];
  15. vector<int> edge[MAX_N];
  16.  
  17. void init_union_find()
  18. {
  19. for(int i=;i<=n;i++)
  20. {
  21. par[i]=i;
  22. }
  23. }
  24.  
  25. int find(int x)
  26. {
  27. return par[x]==x ? x : par[x]=find(par[x]);
  28. }
  29.  
  30. void unite(int x,int y)
  31. {
  32. int px=find(x);
  33. int py=find(y);
  34. if(px==py) return;
  35. par[px]=py;
  36. }
  37.  
  38. bool same(int x,int y)
  39. {
  40. return find(x)==find(y);
  41. }
  42.  
  43. void read()
  44. {
  45. scanf("%d%d%d",&n,&m,&t);
  46. init_union_find();
  47. int x,y;
  48. for(int i=;i<=m;i++)
  49. {
  50. scanf("%d%d",&x,&y);
  51. edge[x].push_back(y);
  52. edge[y].push_back(x);
  53. unite(x,y);
  54. }
  55. }
  56.  
  57. void dfs(int now,int p,int nd,int &v)
  58. {
  59. if(nd>maxd)
  60. {
  61. maxd=nd;
  62. v=now;
  63. }
  64. for(int i=;i<edge[now].size();i++)
  65. {
  66. int temp=edge[now][i];
  67. if(temp!=p) dfs(temp,now,nd+,v);
  68. }
  69. }
  70.  
  71. void work()
  72. {
  73. for(int i=;i<=n;i++)
  74. {
  75. if(find(i)==i)
  76. {
  77. maxd=-;
  78. dfs(i,-,,op);
  79. maxd=-;
  80. dfs(op,-,,ed);
  81. d[i]=maxd;
  82. }
  83. }
  84. int opt,x,y;
  85. while(t--)
  86. {
  87. scanf("%d",&opt);
  88. if(opt==)
  89. {
  90. scanf("%d",&x);
  91. printf("%d\n",d[find(x)]);
  92. }
  93. else
  94. {
  95. scanf("%d%d",&x,&y);
  96. if(!same(x,y))
  97. {
  98. d[find(y)]=max(max(d[find(x)],d[find(y)]),
  99. (int)(ceil(d[(find(x))]/2.0)+ceil(d[find(y)]/2.0)+));
  100. unite(x,y);
  101. }
  102. }
  103. }
  104. }
  105.  
  106. int main()
  107. {
  108. read();
  109. work();
  110. }

Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】的更多相关文章

  1. cf1278D——树的性质+并查集+线段树/DFS判环

    昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...

  2. Codeforces 455C Civilization(并查集+dfs)

    题目链接:Codeforces 455C Civilization 题目大意:给定N.M和Q,N表示有N个城市,M条已经修好的路,修好的路是不能改变的.然后是Q次操作.操作分为两种.一种是查询城市x所 ...

  3. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  4. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  5. Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G题, 并查集 + 线段树合并)

    题目链接  2016 ACM-ICPC EC-Final Problem G 题意  给定一个无向图.每个点有一种颜色. 现在给定$q$个询问,每次询问$x$和$w$,求所有能通过边权值不超过$w$的 ...

  6. POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)

    传送门 The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8690   Acce ...

  7. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  8. [BZOJ3038]上帝造题的七分钟2 树状数组+并查集

    考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...

  9. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  10. 【BZOJ4025】二分图(线段树分治,并查集)

    [BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...

随机推荐

  1. centos 防火墙开放80端口

    辛辛苦苦编译安装完Ngnix,mysql ,PHP,后发现不能访问,后来发现是防火墙把80端口给禁用了.开启之:(以下参考自:http://llhdf.javaeye.com/blog/526176) ...

  2. excel批量取消隐藏工作表

    按下"Alt+F11"键,在打开的"Microsoft Bisual Basic"窗口中,选择"插入——模块".,复制下面的代码,按F5键运 ...

  3. Python调用API接口的几种方式 数据库 脚本

    Python调用API接口的几种方式 2018-01-08 gaoeb97nd... 转自 one_day_day... 修改 微信分享: 相信做过自动化运维的同学都用过API接口来完成某些动作.AP ...

  4. 【Python web自动化】之读取配置文件参数,利用cookie返回值进行跳过验证码进行登录操作

    当进行Python的Web自动化时,会涉及到验证码问题,该如何跳过执行呢,下面请看代码: 1.首先新建配置文件*.ini格式 config.ini [db] #基础地址: baseurl = http ...

  5. 如何使CSS--better(系列二)

    上一篇文章(如何使CSS--beter 系列一)中  分析了一下 什么样子的代码是高效的 应该避免什么样子的代码, 那么什么样子的代码是更容易扩展的? 什么代码是更好维护的? 什么代码是更好的? 下边 ...

  6. 解决ListView滑动上下出现阴影

    网上大部分说在listview的属性中通过设置android:fadingEdge="none"来解决问题,需要说明的是是在2.3版本之前有效! 方法一. public class ...

  7. An Ordinary Game(简单推导)

    An Ordinary Game Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement There ...

  8. POJ 2187 Beauty Contest【凸包周长】

    题目: http://poj.org/problem?id=1113 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  9. php生成条形码: barcodegen

    实例结构: 1. index.html <!DOCTYPE html> <html> <head> <title>Test with embedded ...

  10. SAP ATP邏輯可用性檢查

    [转http://tqmeng.blog.163.com/blog/static/169263916201162002414612/]SAP ATP邏輯可用性檢查1.可用性檢查群組OVZ2主要用於檢查 ...