水题,求助
查看原帖
水题,求助
503822
Essinsop楼主2021/10/30 10:00

恐怕树上直径打错了(?)我家树上直径有点不同..

并茶集缩点+树上直径

#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
int n, w[maxn], head[maxn], tot, ans1, ans2, dp[maxn], fa[maxn], fa2[maxn], faq[maxn], dep[maxn];
struct node {
	int v, pre;
}e[maxn << 1];
void add(int u, int v) {
	e[++tot].v = v;
	e[tot].pre = head[u];
	head[u] = tot;
}
int head2[maxn], tot2;
struct node1 {
	int v, pre;
}e2[maxn << 1];
void added(int u, int v) {
	e2[++tot2].v = v;
	e2[tot2].pre = head2[u];
	head2[u] = tot2;
}
void init() {
	for(int i = 1;i <= n;i++) faq[i] = i;
}
int get(int x) {
	if(x == faq[x]) return x;
	else return faq[x] = get(faq[x]);
}
void com(int u, int v) {
	int t1 = get(u), t2 = get(v);
	if(t1 != t2) faq[t1] = t2;
}
void dfs1(int now) {
	for(int i = head[now];i;i = e[i].pre) {
		int v = e[i].v;
		if(v != fa[now]) {
			fa[v] = now;
			if(w[v] == w[now]) com(v, now);
			dfs1(v);
			if(w[v] != w[now]) added(get(now), get(v)), added(get(v), get(now));
		}
	}
}
void dfs2(int now, int st) {
	bool flag = false;
	for(int i = head2[now];i;i = e2[i].pre) {
		int v = e2[i].v;
		if(v != fa2[now]) {
			flag = true;
			fa2[v] = now;
			dep[v] = dep[now] + 1;
			dfs2(v, st);
			dp[now] = max(dp[now], dp[v] + 1);
		}
	}
	if(!flag) dp[now] = 1;
	if(now == st) {
		for(int i = head2[now];i;i = e2[i].pre) {
			int v = e2[i].v;
			if(dp[v] > ans1) {
				ans2 = ans1;
				ans1 = dp[v];
			}
			else if(dp[v] > ans2 && dp[v] < ans1) {
				ans2 = dp[v];
			}
		}
	}
}
int main() {
	scanf("%d", &n);
	init();
	for(int i = 1;i <= n;i++) scanf("%d", &w[i]);
	for(int i = 1;i <= n - 1;i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		add(u, v);
		add(v, u);
	}
	dfs1(1);
	for(int i = 1;i <= n;i++) {
		if(faq[i] == i) {
			dep[i] = 1;
			dfs2(i, i);
			break;
		}
	}
	cout << (ans1 + ans2 + 1) / 2 << endl;
}
2021/10/30 10:00
加载中...