题目链接:

题目

C. Civilization

time limit per test1 second

memory limit per test256 megabytes

inputstandard input

outputstandard output

问题描述

Andrew plays a game called "Civilization". Dima helps him.

The game has n cities and m bidirectional roads. The cities are numbered from 1 to n. Between any pair of cities there either is a single (unique) path, or there is no path at all. A path is such a sequence of distinct cities v1, v2, ..., vk, that there is a road between any contiguous cities vi and vi + 1 (1 ≤ i < k). The length of the described path equals to (k - 1). We assume that two cities lie in the same region if and only if, there is a path connecting these two cities.

During the game events of two types take place:

Andrew asks Dima about the length of the longest path in the region where city x lies.

Andrew asks Dima to merge the region where city x lies with the region where city y lies. If the cities lie in the same region, then no merging is needed. Otherwise, you need to merge the regions as follows: choose a city from the first region, a city from the second region and connect them by a road so as to minimize the length of the longest path in the resulting region. If there are multiple ways to do so, you are allowed to choose any of them.

Dima finds it hard to execute Andrew's queries, so he asks you to help him. Help Dima.

输入

The first line contains three integers n, m, q (1 ≤ n ≤ 3·105; 0 ≤ m < n; 1 ≤ q ≤ 3·105) — the number of cities, the number of the roads we already have and the number of queries, correspondingly.

Each of the following m lines contains two integers, ai and bi (ai ≠ bi; 1 ≤ ai, bi ≤ n). These numbers represent the road between cities ai and bi. There can be at most one road between two cities.

Each of the following q lines contains one of the two events in the following format:

1 xi. It is the request Andrew gives to Dima to find the length of the maximum path in the region that contains city xi (1 ≤ xi ≤ n).

2 xi yi. It is the request Andrew gives to Dima to merge the region that contains city xi and the region that contains city yi (1 ≤ xi, yi ≤ n). Note, that xi can be equal to yi.

输出

For each event of the first type print the answer on a separate line.

样例

input

6 0 6

2 1 2

2 3 4

2 5 6

2 3 2

2 5 3

1 1

output

4

题意

给你一个森林,进行两个操作:

  • 输入一个x,求x所在的树的直径
  • 输入u,v,把u,v所在的树合并起来

题解

求出每颗树的中心,作为集合的中心。

两颗树合并,只要把直径比较短的树的中心合并到直径比较长的树的中心就可以了。

合并完之后的直径长度为max(r1,r2,(r1+1)/2+(r2+1)/2+1)。其中r1为第一颗树的直径,r2为第二颗树的直径

没写过树的中心,写搓了:

先求树的直径,然后找直径的中间点。连续dfs了三次。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = 3e5+10;
int n, m, q; int fa[maxn],r[maxn];
int find(int x) {
return fa[x] = fa[x] == x ? x : find(fa[x]);
} vector<int> G[maxn];
int vis[maxn];
void dfs(int u, int p, int &len, int &x,int d) {
if (len < d) x = u, len = d;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == p) continue;
dfs(v, u, len, x, d + 1);
}
} bool dfs2(int u, int p, int y, int len,int dep,int &ctr) {
bool ok = 0;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == p) continue;
ok=dfs2(v, u, y, len,dep+1, ctr);
if (ok&&dep == len / 2) ctr = u;
if (ok) return ok;
}
if (u == y) ok = 1;
return ok;
} void dfs3(int u, int p,int ctr) {
vis[u] = 1;
fa[u] = ctr;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == p) continue;
dfs3(v, u, ctr);
}
} void init() {
for (int i = 0; i <= n; i++) fa[i] = i,r[i]=0;
memset(vis, 0, sizeof(vis));
} int main() {
scanf("%d%d%d", &n, &m, &q);
init();
int cmd, u,v,x;
while (m--) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
int ctr, l, x, y;
l = -1; dfs(i, -1, l, x, 0);
l = -1; dfs(x, -1, l, y, 0);
ctr = i;
dfs2(x, -1, y, l,0,ctr);
r[ctr] = l;
dfs3(i, -1,ctr);
}
}
while (q--) {
scanf("%d", &cmd);
if (cmd == 1) {
scanf("%d", &x);
int px = find(x);
printf("%d\n", r[px]);
}
else {
scanf("%d%d", &u, &v);
int pu = find(u), pv = find(v);
if (pu != pv) {
int maxr = max(r[pu], r[pv]);
maxr = max(maxr, (r[pu] + 1) / 2 + (r[pv] + 1) / 2 + 1);
if (r[pu] > r[pv]) fa[pv] = pu, r[pu] = maxr;
else fa[pu] = pv, r[pv] = maxr;
}
}
}
return 0;
}

发现只要求直径就可以了,随便找个点为根,不用找树中心。。orz。。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = 3e5+10;
int n, m, q; int fa[maxn],r[maxn];
int find(int x) {
return fa[x] = fa[x] == x ? x : find(fa[x]);
} vector<int> G[maxn];
int rt;
void dfs(int u, int p, int &len, int &x,int d) {
fa[u] = rt;
if (len < d) x = u, len = d;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (v == p) continue;
dfs(v, u, len, x, d + 1);
}
} void init() {
for (int i = 0; i <= n; i++) fa[i] = i,r[i]=0;
} int main() {
scanf("%d%d%d", &n, &m, &q);
init();
int cmd, u,v,x;
while (m--) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
if (fa[i]==i) {
int l, x, y;
rt = i;
l = -1; dfs(i, -1, l, x, 0);
l = -1; dfs(x, -1, l, y, 0);
r[i] = l;
}
}
while (q--) {
scanf("%d", &cmd);
if (cmd == 1) {
scanf("%d", &x);
int px = find(x);
printf("%d\n", r[px]);
}
else {
scanf("%d%d", &u, &v);
int pu = find(u), pv = find(v);
if (pu != pv) {
int maxr = max(r[pu], r[pv]);
maxr = max(maxr, (r[pu] + 1) / 2 + (r[pv] + 1) / 2 + 1);
if (r[pu] > r[pv]) fa[pv] = pu, r[pu] = maxr;
else fa[pu] = pv, r[pv] = maxr;
}
}
}
return 0;
}

Codeforces Round #260 (Div. 1) C. Civilization 树的中心+并查集的更多相关文章

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

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

  2. Codeforces Round #396 (Div. 2) D. Mahmoud and a Dictionary 并查集

    D. Mahmoud and a Dictionary 题目连接: http://codeforces.com/contest/766/problem/D Description Mahmoud wa ...

  3. Codeforces Round #250 (Div. 1) B. The Child and Zoo 并查集

    B. The Child and Zoo Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/438/ ...

  4. Codeforces Round #360 (Div. 1) D. Dividing Kingdom II 暴力并查集

    D. Dividing Kingdom II 题目连接: http://www.codeforces.com/contest/687/problem/D Description Long time a ...

  5. Codeforces Round #329 (Div. 2) D. Happy Tree Party(LCA+并查集)

    题目链接 题意:就是给你一颗这样的树,用一个$y$来除以两点之间每条边的权值,比如$3->7$,问最后的y的是多少,修改操作是把权值变成更小的. 这个$(y<=10^{18})$除的权值如 ...

  6. Codeforces Round #212 (Div. 2) D. Fools and Foolproof Roads 并查集+优先队列

    D. Fools and Foolproof Roads   You must have heard all about the Foolland on your Geography lessons. ...

  7. Codeforces Round #376 (Div. 2) A B C 水 模拟 并查集

    A. Night at the Museum time limit per test 1 second memory limit per test 256 megabytes input standa ...

  8. Codeforces Round #254 (Div. 2) B. DZY Loves Chemistry (并查集)

    题目链接 昨天晚上没有做出来,刚看题目的时候还把题意理解错了,当时想着以什么样的顺序倒,想着就饶进去了, 也被题目下面的示例分析给误导了. 题意: 有1-n种化学药剂  总共有m对试剂能反应,按不同的 ...

  9. Codeforces Round #385 (Div. 2)A B C 模拟 水 并查集

    A. Hongcow Learns the Cyclic Shift time limit per test 2 seconds memory limit per test 256 megabytes ...

随机推荐

  1. tools安装

    1.ruby安装  下载安装包 勾选中间一个 2.sass 安装  转换TB镜像 $ gem sources --remove https://rubygems.org/$ gem sources - ...

  2. Tomcat - DBCP 配置

    1. Database configuration Create a new test user, a new database and a single test table. Your MySQL ...

  3. Lombok(1.14.8) - @NoArgsConstructor, @RequiredArgsConstructor & @AllArgsConstructor

    @NoArgsConstructor @NoArgsConstructor,提供一个无参的构造方法. package com.huey.hello.bean; import java.util.Dat ...

  4. Asp.net MVC 4 Html帮助类

    Html帮助类 used to render (modify and output) HTML form elements 用来渲染HTML表单元素(修改和输出) Html.ActionLink 输出 ...

  5. 找出文件正在被哪个windows进程使用的方法

    Ever try to delete, move, or rename a file only to get a Windows system warning with something like ...

  6. Unity3d-UI插件EZGUI官方视频教程

    Showcase Teaser (D/L) – Showcases some of the things that can be accomplished using EZ GUI.#1 – Butt ...

  7. 设计模式——设计模式之禅day2

    接口隔离原则 接口分为两种: ● 实例接口( Object Interface) , 在Java中声明一个类, 然后用new关键字产生一个实例, 它是对一个类型的事物的描述, 这是一种接口. 比如你定 ...

  8. Java之绘制二次曲线

    前面已经介绍过绘制方法.这里不再赘述. 画一下草图来看看:灰色表示X值,红色表示Y值. 在这里要值得注意的是:当我们把它们的坐标在纸上画出来时,就会觉得“有问题”了,你看A(60,20,120,100 ...

  9. JSP连接mysql 驱动包

    360网盘 https://yunpan.cn/cPxT6CV9Kydyb  访问密码 1df9

  10. Swift字典类

    在Foundation框架中提供一种字典集合,它是由“键-值”对构成的集合.键集合不能重复,值集合没有特殊要求.键和值集合中的元素可以是任何对象,但是不能是nil.Foundation框架字典类也分为 ...