P3629 [APIO2010] 巡逻
思路
考虑
考虑
考虑
思路出来了,我们来思考实现,出于偷懒,所以我们将两次直径都写成树形
code
#include <iostream> #define h(x) g.h[x] #define nxt(x) g.a[x].nxt #define to(x) g.a[x].to #define w(x) g.a[x].w using namespace std; using pii = pair<int, int>; const int MaxN = 1e5 + 10; struct Edge { struct Node { int to, w, nxt; } a[MaxN << 1]; int h[MaxN], cnt; Edge() { cnt = 1; fill(h, h + MaxN + 1, -1); } void insert(int x, int y) { a[++cnt] = {y, 1, h[x]}, h[x] = cnt; a[++cnt] = {x, 1, h[y]}, h[y] = cnt; } } g; int n, k, s1, s2, res; pii f[MaxN][2]; void DFS(int x, int fa, int &y) { f[x][0] = f[x][1] = {0, x}; for (int i = h(x); ~i; i = nxt(i)) { if (to(i) == fa) continue; DFS(to(i), x, y); pii t = f[to(i)][0]; t.first += w(i); if (t >= f[x][0]) f[x][1] = f[x][0], f[x][0] = t; else if (t > f[x][1]) f[x][1] = t; } if (f[y][0].first + f[y][1].first < f[x][0].first + f[x][1].first) y = x; } bool GO(int x, int fa, int y) { if (y == x) return 1; int res = 0; for (int i = h(x); ~i; i = nxt(i)) { if (to(i) == fa) continue; if (GO(to(i), x, y)) res = 1, w(i) = w(i ^ 1) = -1; } return res; } int main() { cin >> n >> k; for (int i = 1, u, v; i < n; i++) { cin >> u >> v, g.insert(u, v); } DFS(1, -1, s1), res = (f[s1][0].first + f[s1][1].first - 1); if (k == 1) return cout << 2 * (n - 1) - res << endl, 0; GO(s1, -1, f[s1][0].second), GO(s1, -1, f[s1][1].second); DFS(1, -1, s2); cout << 2 * (n - 1) - (f[s2][0].first + f[s2][1].first + res - 1) << endl; return 0; }
本文作者:yabnto
本文链接:https://www.cnblogs.com/ybtarr/p/18244871
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步