题解:P15902 [TOPC 2025] Gas Station
XFrostKris · · 题解
题意
一个树上,可以放置
解决
发现
考虑树上dp。
我们定义
设
若
记最大的
最后
相应维护
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5+5;
const int INF = 0x3f3f3f3f;
int n, k;
struct edge {
int v, w;
};
vector<edge>e[N];
int l = 0, r = 0;
int f[N], g[N];
void dfs(int u, int fa, int x) {
int mx = -1e18, snd = -1e18;
for (auto [v, w] : e[u]) {
if (v == fa) continue;
dfs(v, u, x);
if (g[v] + w > x) g[v] = 0, f[v] += 1;//v上放个
snd = max(snd, min(mx, g[v] + w));
mx = max(mx, g[v] + w);
g[u] = max(g[u], g[v] + w);
}
if (snd + mx > x) f[u] += 1, g[u] = 0; //u上放个
for (auto [v, w] : e[u]) {
if (v == fa) continue;
f[u] += f[v];
}
}
bool check(int x) {
for (int i = 0; i <= n; i++) f[i] = g[i] = 0;
dfs(1, 0, x);
return f[1] <= k;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> k;
for (int i = 1, u, v, w; i < n; i++) {
cin >> u >> v >> w;
e[u].push_back({v, w});
e[v].push_back({u, w});
l = max(l, w);
r += w;
}
int ans = 0;
while (l <= r) {
int mid = l + r >> 1;
if (check(mid)) r = mid - 1, ans = mid;
else l = mid + 1;
}
cout << ans;
return 0;
}
时间复杂度