CF455C Civilization

题目传送门

这是一道双倍经验题 Luogu P2195
虽然Luogu P2195的题意很迷,但确实是双倍经验


先预处理出每棵树的直径,并用并查集维护哪些点在同一棵树里
对于\(1\)操作,直接输出就可以了
对于\(2\)操作,显然在两棵树直径的中点处连边最优。再用并查集维护一下即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
LL read() {
	LL k = 0, f = 1; char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
		k = k * 10 + c - 48, c = getchar();
	return k * f;
}
struct zzz {
	int t, nex;
}e[300010 << 1]; int head[300010], tot;
void add(int x, int y) {
	e[++tot].t = y;
	e[tot].nex = head[x];
	head[x] = tot;
}
int fa[300010];
int findd(int x) {
	return fa[x] == x ? x : fa[x] = findd(fa[x]);
}
int que[300010], dis[300010], h, t;
int dia[300010];
void solve(int s) {
	h = 1, t = 0; que[++t] = s; dis[s] = 1;
	int maxn = -1, pos;
	while(h <= t) {
		int x = que[h++];
		if(dis[x] > maxn) maxn = dis[x], pos = x;
		for(int i = head[x]; i; i = e[i].nex) {
			if(!dis[e[i].t])
				que[++t] = e[i].t, dis[e[i].t] = dis[x] + 1;
		}
	}
	for(int i = 1; i <= t; ++i) dis[que[i]] = 0;
	h = 1, t = 0, que[++t] = pos; dis[pos] = 1;
	maxn = -1;
	while(h <= t) {
		int x = que[h++];
		if(dis[x] > maxn) maxn = dis[x];
		for(int i = head[x]; i; i = e[i].nex) {
			if(!dis[e[i].t])
				que[++t] = e[i].t, dis[e[i].t] = dis[x] + 1;
		}
	}
	int fx = findd(s);
	dia[fx] = maxn-1;
}
int main() {
	int n = read(), m = read(), q = read();
	for(int i = 1; i <= n; ++i) fa[i] = i;
	for(int i = 1; i <= m; ++i) {
		int x = read(), y = read();
		int fx = findd(x), fy = findd(y);
		if(fx != fy) fa[fx] = fy;
		add(x, y); add(y, x);
	}
	for(int i = 1; i <= n; ++i)
		if(!dis[i]) solve(i);
	for(int i = 1; i <= q; ++i) {
		int opt = read(), x = read();
		if(opt == 1) {
			int fx = findd(x);
			printf("%d\n", dia[fx]);
		}
		else {
			int y = read();
			int fx = findd(x), fy = findd(y);
			if(fx != fy) {
				fa[fx] = fy;
				dia[fy] = max((dia[fx]+1 >> 1) + (dia[fy]+1 >> 1) + 1, max(dia[fx], dia[fy]));
			}
		}
	}
	return 0;
}
posted @ 2019-11-14 11:41  MorsLin  阅读(108)  评论(0编辑  收藏  举报