题解 P2971【[USACO10HOL]Cow Politics G】
似乎是一个很简洁的新做法。
显然 个点集互不干扰,可以分开处理。
对于每个点集,首先取出两个点 作为最远的两个点(为表述方便下文称为直径),然后考虑向点集中加入点 的过程。我们计算出 ,则点集的直径为 。判断出哪两个点是新的直径,然后在这个新的直径的基础上继续加点即可。
正确性的话,类似于正常的树的直径,到一个点距离最远的点一定是一条直径的端点。若新的点要作为直径端点,只能是到原来直径两端距离有一个比原来直径要长。
时间复杂度 。
// Problem: P2971 [USACO10HOL]Cow Politics G
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2971
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x,y,z) for(int x=(y);x<=(z);x++)
#define per(x,y,z) for(int x=(y);x>=(z);x--)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const int N = 2e5+5;
int n, k, a[N], fa[N][19], dis[N], rt;
vector<int> d[N], e[N];
template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}
void dfs(int u) {
dis[u] = dis[fa[u][0]] + 1;
rep(i, 1, 18) fa[u][i] = fa[fa[u][i-1]][i-1];
for(int v : e[u]) dfs(v);
}
int LCA(int u, int v) {
if(dis[u] < dis[v]) swap(u, v);
per(i, 18, 0) if(dis[fa[u][i]] >= dis[v]) u = fa[u][i];
if(u == v) return u;
per(i, 18, 0) if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
return fa[u][0];
}
int dist(int u, int v) {
return dis[u] + dis[v] - 2 * dis[LCA(u, v)];
}
int main() {
scanf("%d%d", &n, &k);
rep(i, 1, n) {
scanf("%d%d", &a[i], &fa[i][0]);
if(!fa[i][0]) rt = i;
d[a[i]].push_back(i);
e[fa[i][0]].push_back(i);
}
dfs(rt);
rep(i, 1, k) {
int u = d[i][0], v = d[i][1], sz = d[i].size();
for(int j=2;j<sz;j++) {
int w = d[i][j];
int d1 = dist(u, v), d2 = dist(u, w), d3 = dist(v, w);
int diameter = max(d1, max(d2, d3));
int U = 0, V = 0;
if(d1 == diameter) U = u, V = v;
else if(d2 == diameter) U = u, V = w;
else U = v, V = w;
u = U; v = V;
}
printf("%d\n", dist(u, v));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】