题目链接: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:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#define MAX_N 300005 using namespace std; int n,m,t;
int maxd;
int op,ed;
int d[MAX_N];
int par[MAX_N];
vector<int> edge[MAX_N]; void init_union_find()
{
for(int i=;i<=n;i++)
{
par[i]=i;
}
} int find(int x)
{
return par[x]==x ? x : par[x]=find(par[x]);
} void unite(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py) return;
par[px]=py;
} bool same(int x,int y)
{
return find(x)==find(y);
} void read()
{
scanf("%d%d%d",&n,&m,&t);
init_union_find();
int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
edge[x].push_back(y);
edge[y].push_back(x);
unite(x,y);
}
} void dfs(int now,int p,int nd,int &v)
{
if(nd>maxd)
{
maxd=nd;
v=now;
}
for(int i=;i<edge[now].size();i++)
{
int temp=edge[now][i];
if(temp!=p) dfs(temp,now,nd+,v);
}
} void work()
{
for(int i=;i<=n;i++)
{
if(find(i)==i)
{
maxd=-;
dfs(i,-,,op);
maxd=-;
dfs(op,-,,ed);
d[i]=maxd;
}
}
int opt,x,y;
while(t--)
{
scanf("%d",&opt);
if(opt==)
{
scanf("%d",&x);
printf("%d\n",d[find(x)]);
}
else
{
scanf("%d%d",&x,&y);
if(!same(x,y))
{
d[find(y)]=max(max(d[find(x)],d[find(y)]),
(int)(ceil(d[(find(x))]/2.0)+ceil(d[find(y)]/2.0)+));
unite(x,y);
}
}
}
} int main()
{
read();
work();
}

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. maven+eclipse+mac+tomcat 多模块发布

    之前项目中有用到过maven,但是没运行过web的maven,所以这里记录一下. 项目的结构: ---master  //parent ---web-project // ---client-proj ...

  2. 小技巧之Selenium如何切换到弹出的Tab页中

    今天群里讨论了一个问题,如何将selenium的操作焦点切换到浏览器中新弹出来的Tab页中,正好对应到了昨天的那篇文章“小技巧之在浏览器中打开新的页签”.今天就带大家来解决这个问题: 先封装一个Tab ...

  3. PHP压缩上传图片

    最近手上的项目页面要显示很多图片,虽然用了jQuery的lazyload,但是效果并没理想,滑动到一个区域还要比较长的时间图片才完全显示出来.于是想着将上传上去的900KB+压缩备份一份缩略图. PH ...

  4. 通过pyenv进行多版本python管理

    1.安装pyenv brew install pyenv 2.配置.zshrc文件 export PYENV_ROOT=/usr/local/var/pyenv if which pyenv > ...

  5. mysql导出数据库提示警告在GTID模式下面

    [root@db02 tmp]# mysqldump -S /tmp/mysql.sock -A -R --triggers --master-data=2 --single-transaction ...

  6. Robot Motion - poj 1573

      Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11269   Accepted: 5486 Description A ...

  7. AR9331出现connect-debounce failed,port 1 disabled解决方法备忘

    基于AR9331的路由器,自己画的pcb板子,居然出现这个错误,百度下,貌似有不少人遇见过这个错误,可是在改动板子前我的固件用的是没问题的.USB完美使用 改动过板子后出现这个问题! hub 1-0: ...

  8. ubuntu 解决更换源失败问题

    用图形界面命令打开窗口在终端输入 gksudo nautilus打开一个图形窗口 (注意在这个图形窗口下 任何目录下的文件都是可以删除的) /ect/apt删除下面的sources.list和备份文件 ...

  9. Android自定义View分析

    一.基本步骤 1.自定义View的属性 2.在View的构造方法中获取自定义属性 3.重写onMesure方法(非必须) 4.重写onDraw方法 二.具体实现 1.自定义View的属性,首先在res ...

  10. python 正則表達式推断邮箱格式是否正确

    import re def validateEmail(email):     if len(email) > 7:         if re.match("^.+\\@(\\[?) ...