1427 文明

题目来源: CodeForces

基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
 

安德鲁在玩一个叫“文明”的游戏。大妈正在帮助他。

这个游戏里面有n个城市和m条双向的道路。城市从1到n编号。对于每一对城市,他们之间要么有唯一的一条道路,要么就是不可互达。一条道路的定义是一个包含不同城市的序列 v1, v2,...,vk ,  vi  和  vi+1 (1≤ i < k)之间有直接的一条道路相连。这条道路的长度是k-1。两个城市在同一区域的条件是当且仅当他们之间可以互达。

在游戏过程中,会有两个事件。

1.    安德鲁问大妈,城市x所在的区域里面最长的道路是多长。

2.    安德鲁要求大妈,合并城市x和城市y所在的区域。如果这两个城市本来在同一个区域,那么就不用合并。否则合并两个区域:从城市x所在区域选一个城市,再从城市y所在区域选一个城市,然后给这两个城市连一条边。选择这两个城市的时候要使得合并之后的区域里面最长道路尽可能小。如果有多种方案,任选一种即可。

大妈发现这些问题好难哦,所以他想请你来帮助一下。

Input
单组测试数据。
第一行包含三个整数n,m,q(1 ≤ n ≤ 3*10^5; 0 ≤ m < n; 1 ≤ q ≤ 3*10^5),分别表示城市数目,道路数目,查询数目。
接下来m行,每行有两个整数 ai 和bi (ai ≠ bi; 1 ≤ ai, bi ≤ n)。表示ai和bi之间有一条直接相连的道路。两个城市之间最多有一条直接相连的道路。
接下来q行的格式是下列之一:
1 xi 。(1 ≤ xi ≤ n)。这种情况要查询当前xi所在的区域的最长道路。
2 xi yi。 (1 ≤ xi, yi ≤ n)。这种情况下要求合并xi和yi所在的区域。注意:xi和yi可能是一样的。
Output
对于第1类查询,输出当前区域的最长路径长度。
Input示例
6 0 7
2 1 2
2 3 4
2 5 6
2 3 2
2 5 3
1 1
1 1
Output示例
4
4
/*
51 nod 1427 文明 (并查集 + 树的直径) problem:
给你n个城市,m条双向边连接,然后是q个查询
1 x: 城市x所在的区域的最长道路
2 x y:将两个城市的所在区域连接,要求维护最长路最短. solve:
一个区域的最长路就相当于树的直径.因为两个城市之间最多只有一条路径.
合并的话,如果要求最短,那么相当于将两条直径的中点相连. 所以已知A,B的直径可计算出新的直径的值
(注意还要与A,B的直径进行下比较).
先处理出每个区域的树的直径.然后可给每个区域打上标记,用并查集合并维护一下区域的树的直径. hhh-2016/09/27-17:21:09
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <math.h>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
using namespace std;
const int maxn = 3e5 + 100;
const int inf = 0x3f3f3f3f;
const ll mod = 1000000007;
const double eps = 1e-7;
template<class T> void read(T&num)
{
char CH;
bool F=false;
for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p)
{
if(!p)
{
puts("0");
return;
}
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
} struct node
{
int v,next;
} edge[maxn << 1];
ll Max;
int tot,pos;
int head[maxn];
int vis[maxn];
//int ans[i];
int pre[maxn];
struct Node
{
ll dis;
int pre;
} pnode[maxn];
void init(int n)
{
memset(head,-1,sizeof(head));
tot = 0;
for(int i = 1; i <= n; i++)
{
vis[i] = 0;
pnode[i].pre = i;
pnode[i].dis = 1;
}
}
void add_edge(int u,int v)
{
edge[tot].v = v,edge[tot].next = head[u],head[u] = tot ++;
} void dfs(int u,int fa,ll len,int anc)
{
vis[u] = 1;
pnode[u].pre = anc;
if(len > Max)
{
Max = len;
pos = u;
} for(int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].v;
if(v == fa)
continue;
dfs(v,u,len + 1LL,anc);
}
} void cal(int now)
{
int from;
pos = 0,Max =0 ;
dfs(now,-1,0,now);
from = pos;
pos = 0,Max = 0;
dfs(from,-1,0,now);
pnode[now].dis = Max;
} int fin(int u)
{
if(pnode[u].pre != u)
return pnode[u].pre = fin(pnode[u].pre);
return u;
} void unio(int u,int v)
{
int ta = fin(u);
int tb = fin(v); if(ta == tb)
return ;
if(ta > tb)
swap(ta,tb);
pnode[ta].pre =tb;
ll tMax = 0;
tMax = max(pnode[ta].dis,pnode[tb].dis);
tMax = max(tMax,(pnode[ta].dis+1LL)/2LL+(pnode[tb].dis + 1LL)/2LL + 1LL);
pnode[tb].dis = tMax;
pnode[ta].dis= tMax;
} int main()
{
int n,m,q;
int u,v,ob;
read(n),read(m),read(q);
init(n);
for(int i = 1; i <= m; i++)
{
read(u),read(v);
add_edge(u,v);
add_edge(v,u);
}
for(int i = 1;i <= n;i++)
{
if(!vis[i])
cal(i);
}
for(int i = 1; i <= q; i++)
{
read(ob);
if(ob == 1)
{
read(u);
int ta = fin(u);
print(pnode[ta].dis);
}
else
{
read(u),read(v);
unio(u,v);
}
}
return 0;
}

  

51 nod 1427 文明 (并查集 + 树的直径)的更多相关文章

  1. 51 nod 1515 明辨是非(并查集合并)

    1515 明辨是非题目来源: 原创基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 给n组操作,每组操作形式为x y p. 当p为1时,如果第x变量和第y个变量可以 ...

  2. 【bzoj3362/3363/3364/3365】[Usaco2004 Feb]树上问题杂烩 并查集/树的直径/LCA/树的点分治

    题目描述 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样, 图中农场用F ...

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

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

  4. 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树

    正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...

  5. BZOJ-3211花神游历各国 并查集+树状数组

    一开始想写线段树区间开方,简单暴力下,但觉得变成复杂度稍高,懒惰了,编了个复杂度简单的 3211: 花神游历各国 Time Limit: 5 Sec Memory Limit: 128 MB Subm ...

  6. BZOJ3211 花神游历各国 并查集 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3211 题意概括 有n个数形成一个序列. m次操作. 有两种,分别是: 1. 区间开根(取整) 2. ...

  7. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

  8. 【bzoj4869】[Shoi2017]相逢是问候 扩展欧拉定理+并查集+树状数组

    题目描述 Informatik verbindet dich und mich. 信息将你我连结. B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 ...

  9. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

随机推荐

  1. Beta预备

    团队名称:稳住!我们能赢 Beta预备: 讨论组长是否重选的议题和结论 项目组长可以说是一个团队的灵魂和核心.一个好的领导者可以激发团队成员的工作热情,提高开发效率,保质保量的完成工作.虽然在Alph ...

  2. OpenShift实战(一):OpenShift高级安装

    1.1 服务器基本信息 本次安装采用一个master.5个node.3个etcd,node节点两块硬盘,60G磁盘用于docker storage,xxx改为自己的域名或主机名. 节点 功能 IP 内 ...

  3. 【learning】多项式相关(求逆、开根、除法、取模)

    (首先要%miskcoo,这位dalao写的博客(这里)实在是太强啦qwq大部分多项式相关的知识都是从这位dalao博客里面学的,下面这篇东西是自己对其博客学习后的一些总结和想法,大部分是按照其博客里 ...

  4. keepalive配置支持ipv6、ipv4双棧支持

    因公司业务需要,keepalived需要同时支持ipv6和ipv4 keepalived版本1.2.23. keepalived 配置: 重点:ipv6的虚IP配置在 virtual_ipaddres ...

  5. 【iOS】 含tableView的ViewController基类的实现

    上篇博客写了ViewController的基类的实现,这篇博客主要写在BaseViewController的基础上实现一个含tableView控件的基类的实现,主要给包含tableView的页面来继承 ...

  6. jsp和servlet的区别和联系

    jsp和servlet的区别和联系:1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能 ...

  7. golang-在gin中cookie跨域设置(配合ajax)

    1.当我在golang中,在前后端分离的情况下使用cookies时发现,跨域没有被允许.代码如下: func AccessJsMiddleware() gin.HandlerFunc { return ...

  8. .NET反编译工具:de4dot

    de4dot是一款C#编写的基于GPLv3协议的一个开源的.net反混淆脱壳工具,是目前.net下非常不错的一款反编译工具. 支持如下混淆器: Agile.NET (aka CliSecure) Ba ...

  9. Android:ImageView控件显示图片

    1)android显示图片可以使用imageView来呈现,而且也可以通过ImageButton来实现给button添加图片. 2)在创建一个ImageView后,显示图片绑定元素是:android: ...

  10. axios介绍与使用说明 axios中文文档

    本周在做一个使用vuejs的前端项目,访问后端服务使用axios库,这里对照官方文档,简单记录下,也方便大家参考. Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node ...