题目链接:http://codeforces.com/contest/456/problem/E

题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种:

1 x,输出x所在的联通块的最长路;

2 x y,若x和y在同一联通块,则不操作;若不在同一联通块,则选择这两个联通块的各一个城市连一条边,使新的联通块的最长路最短,若有多种选择则随便选。

题解:就是先求出一开始几个连通块的最长路,然后之后q个操作没必要真正意义上连边,只要用并查集更新一下就行了,最后代码有些事要优化的具体看一下代码。

还有求最长路就是求数的直径就行,树的直径就是两遍dfs or bfs。

  1. #include <iostream>
  2. #include <queue>
  3. #include <cstring>
  4. #include <cstdio>
  5. using namespace std;
  6. const int M = 3e5 + 10;
  7. int f[M] , dis[M] , head[M] , e;
  8. void init(int n) {
  9. for(int i = 1 ; i <= n ; i++) f[i] = i;
  10. memset(dis , 0 , sizeof(dis));
  11. memset(head , -1 , sizeof(head));
  12. e = 0;
  13. }
  14. struct Edge {
  15. int u , v , next;
  16. }edge[M << 1];
  17. void add(int u , int v) {
  18. edge[e].v = v;
  19. edge[e].next = head[u];
  20. head[u] = e++;
  21. }
  22. int find(int x) {
  23. if(x == f[x]) return x;
  24. int tmp = find(f[x]);
  25. return f[x] = tmp;
  26. }
  27. struct TnT {
  28. int pos , step;
  29. TnT(){}
  30. TnT(int pos , int step):pos(pos) , step(step) {}
  31. };
  32. bool vis[M] , vs[M];
  33. int maxi , maxd , father;
  34. void dfs(int u , int pre , int step) {
  35. f[u] = father;
  36. if(step > maxd) {
  37. maxd = step;
  38. maxi = u;
  39. }
  40. for(int i = head[u] ; i != -1 ; i = edge[i].next) {
  41. int v = edge[i].v;
  42. if(v == pre) continue;
  43. dfs(v , u , step + 1);
  44. }
  45. }
  46. int main() {
  47. int n , m , q;
  48. scanf("%d%d%d" , &n , &m , &q);
  49. init(n);
  50. for(int i = 0 ; i < m ; i++) {
  51. int u , v;
  52. scanf("%d%d" , & u , &v);
  53. add(u , v);
  54. add(v , u);
  55. //一开始的时候先不要直接并查集如果一开始就并查集的话后面就一定会用到find函数,这样会超时的。
  56. }
  57. for(int i = 1 ; i <= n ; i++) {
  58. if(f[i] == i) {
  59. father = i;
  60. //在求最长路的同时进行并查集,父节点全都定为i这样就不会超时了。优化就在这里,稍微注意一下就行。
  61. maxd = -1;
  62. dfs(i , -1 , 0);
  63. maxd = -1;
  64. dfs(maxi , -1 , 0);
  65. dis[i] = maxd;
  66. }
  67. }
  68. while(q--) {
  69. int x , y , t;
  70. scanf("%d" , &t);
  71. if(t == 1) {
  72. scanf("%d" , &x);
  73. int gg = find(x);
  74. printf("%d\n" , dis[gg]);
  75. }
  76. else {
  77. scanf("%d%d" , &x , &y);
  78. int a = find(x) , b = find(y);
  79. if(a == b) continue;
  80. else {
  81. f[a] = b;
  82. dis[b] = max(max(dis[a] , dis[b]) , (dis[a] + 1) / 2 + (dis[b] + 1) / 2 + 1);
  83. //两个连通块连在一起怎么使得连在一起后使得这个连通块的最长路尽量的短,那么显然要中点和中点连在一起。
  84. }
  85. }
  86. }
  87. return 0;
  88. }

codeforces 456 E. Civilization(并查集+数的直径)的更多相关文章

  1. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

  2. Codeforces Round #260 (Div. 1) C. Civilization 并查集,直径

    C. Civilization Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/455/probl ...

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

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

  4. CodeForces 455C Civilization (并查集+树的直径)

    Civilization 题目链接: http://acm.hust.edu.cn/vjudge/contest/121334#problem/B Description Andrew plays a ...

  5. Codeforces 859E Desk Disorder 并查集找环,乘法原理

    题目链接:http://codeforces.com/contest/859/problem/E 题意:有N个人.2N个座位.现在告诉你这N个人它们现在的座位.以及它们想去的座位.每个人可以去它们想去 ...

  6. Codeforces Gym 100463E Spies 并查集

    Spies Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Desc ...

  7. Codeforces - 828C String Reconstruction —— 并查集find()函数

    题目链接:http://codeforces.com/contest/828/problem/C C. String Reconstruction time limit per test 2 seco ...

  8. CodeForces 731C C - Socks 并查集

    Description Arseniy is already grown-up and independent. His mother decided to leave him alone for m ...

  9. CodeForces 722C Destroying Array (并查集)

    题意:给定 n 个数,然后每次破坏一个位置的数,那么剩下的连通块的和最大是多少. 析:用并查集来做,从后往前推,一开始什么也没有,如果破坏一个,那么我们就加上一个,然后判断它左右两侧是不是存在,如果存 ...

随机推荐

  1. RocketMQ中Broker的启动源码分析(一)

    在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...

  2. 基于vue2.0搭建项目流程

    搭建vue2.0项目--myproject 一. 环境搭建: 1 打开命令行(cmd) 2 安装node node官网 3 安装 vue-cli步骤如下: npm install -g vue-cli ...

  3. Filebeat6.3文档—Log input配置

    Filebeat6.3文档-Log input配置 paths 日志加载的路径.例如加载某一子目录级别下面路径的日志:/var/log/*/*.log.这表示会去加载以.log结尾的/var/log下 ...

  4. java-极光推送教程

    一.准备工作: 1.访问极光推送官网:https://www.jiguang.cn/accounts/login/form 2.注册登陆,拿到appKey和masterSecret 3.创建一个应用, ...

  5. Spring Cloud下基于OAUTH2+ZUUL认证授权的实现

    Spring Cloud下基于OAUTH2认证授权的实现 在Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认 ...

  6. 关于JVM内存溢出的原因分析及解决方案探讨

    前言:JVM中除了程序计数器,其他的区域都有可能会发生内存溢出. 0.什么是内存溢出 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出. 1. ...

  7. sublime text 3 15个常用插件介绍

    1.ColorPicker 功能:调色板(需要输入颜色时,可直接选取颜色) 使用:快捷键Windows: ctrl+shift+c 2.Emmet 功能:编码快捷键,前端必备 使用:在输入代码段后,按 ...

  8. android ——ListView

    谷歌官方文档的介绍:https://developer.android.com/reference/android/widget/ListView.html 显示可垂直滚动的视图集合,其中每个视图都立 ...

  9. 性能测试学习第二天-----loadrunner常用函数大全及设置项

    常用函数大全: 1,C语言参数转web参数 lr_save_string("aaa","param"):将字符串“aaa”或者一个字符串变量,转变成LR的参数{ ...

  10. 终于找到可以一文多发的平台了! openwrite.cn

    openwrite.cn 一文多发平台 有时候自己辛苦写了几个小时的技术文章,被爬虫抓走.自己去全平台一个一个发,又过于麻烦.而且每个平台都不一样,发文同步很困难.那么终于有了一款一文多发的利器:Op ...