80分求调
查看原帖
80分求调
55429
_doudou楼主2024/12/5 10:07
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e4 + 10;
int n, m;
typedef pair<int, int> P;
vector<P> edge[MAXN];
int dp[MAXN], g[MAXN];//dp[i]:表示以i为根的子树中修建赛道条数,g[i]表示以i为根子树不能修建赛道的剩余路径最大值

void dfs(int u, int x, int fa) {
	vector<int> a;
	for (auto e : edge[u]) {
		int v = e.first;
		int w = e.second;
		if (v == fa)
			continue;
		dfs(v, x, u);
		dp[u] += dp[v];
		a.push_back(g[v] + w);
	}
	int cnt = a.size();
	if (cnt != 0) {
		sort(a.begin(), a.end());
		int ll = 0, rr = cnt - 1;
		while (a[rr] >= x) {//大于x的直接自身为一个赛道
			dp[u]++;
			rr--;
		}
		while (ll < rr) {
			if (a[ll] + a[rr] >= x) {//在左边找到与最大值配对的,赛道数+1,右指针--
				dp[u]++;
				rr--;
			} else {//找不到配对的,ll位置有可能是最后剩余的最大值
				g[u] = a[ll];
			}
			ll++;//无论怎样左端点都++
		}
		if (ll == rr)//最后一个若没有找到配对,记录成为最大值
			g[u] = a[ll];
	}

}

bool check(int x) {
	memset(dp, 0, sizeof dp);
	memset(g, 0, sizeof g);
	dfs(1, x, 0);
	return dp[1] >= m;
}

int main() {
	cin >> n >> m;
	int l = INT_MAX, r = 0;
	for (int i = 1; i <= n - 1; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		edge[u].push_back(P(v, w));
		edge[v].push_back(P(u, w));
		l = min(l, w);
		r += w;
	}
	int ans = l;
	while (l <= r) {
		int mid = (l + r) >> 1;
		if (check(mid)) {
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	cout << ans;
	return 0;
}
2024/12/5 10:07
加载中...