树形DP 13pts 求助
查看原帖
树形DP 13pts 求助
865758
sorasaki_hina楼主2023/7/26 19:43

rt,拍了一个下午没结果

#include<bits/stdc++.h>
#define ll long long
#define ma 2010
using namespace std;
const ll mod = 998244353;
//---------------------------------
ll read() {
	ll x = 0, f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-') f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * f;
}
//---------------------------------
ll n, m, k;
ll h[ma];
//---------------------------------
ll head[ma], ver[ma], nxt[ma], tot = 0;
void add(ll x, ll y) {
	ver[++tot] = y;
	nxt[tot] = head[x], head[x] = tot;
}
void Add(ll x, ll y) {
	add(x, y), add(y, x);
}
ll d[ma];
//---------------------------------
ll fa[ma], top[ma], siz[ma], son[ma], dep[ma];
void dfs1(ll x) {
	siz[x] = 1;
	dep[x] = dep[fa[x]] + 1;
	for (ll i = head[x];i;i = nxt[i]) {
		ll y = ver[i];
		if (y == fa[x]) continue;
		fa[y] = x;
		dfs1(y);
		siz[x] += siz[y];
		if (siz[son[x]] < siz[y]) son[x] = y;
	}
}
void dfs2(ll x, ll tp) {
	top[x] = tp;
	if (!son[x]) return;
	dfs2(son[x], tp);
	for (ll i = head[x];i;i = nxt[i]) {
		ll y = ver[i];
		if (y == fa[x] || y == son[x]) continue;
		dfs2(y, y);
	}
}
ll LCA(ll x, ll y) {
	while (top[x] != top[y]) dep[top[x]] > dep[top[y]] ? x = fa[top[x]] : y = fa[top[y]];
	return x > y ? y : x;
}
//---------------------------------
ll dis[ma];
void get_dis(ll x) {
	dis[x] = d[x];
	for (ll i = head[x];i;i = nxt[i]) {
		ll y = ver[i];
		if (y == fa[x]) continue;
		get_dis(y);
		dis[x] += dis[y];
	}
}
//---------------------------------
ll dp[ma][ma];
bool can[ma][ma];
ll lim;
void init(ll x, ll fat, ll bef) {
	can[bef][x] = 1;
	// cout << bef << " " << x << " " << endl;
	for (ll i = head[x];i;i = nxt[i]) {
		ll y = ver[i];
		// cout << x << " -- " << y << endl;;
		// cout << h[bef] << " - " << h[y] << " " << lim << endl;
		// if (h[y] < h[bef]) cout << "nm" << endl;
		// if (h[y] - h[bef] > lim) cout << "sl" << endl;
		if (y == fat) continue;
		if (h[y]<h[bef] || h[y] - h[bef]>lim) continue;
		init(y, x, bef);
	}
}
void dfs(ll x, ll fat) {
	for (ll i = 1;i <= n;i++) {
		if (can[i][x]) dp[i][x] = 0;
		else dp[i][x] = 0x3f3f3f3f3f3f3f3f;
	}
	for (ll i = head[x];i;i = nxt[i]) {
		ll y = ver[i];
		if (y == fat) continue;
		dfs(y, x);
		ll minn = 0x3f3f3f3f3f3f3f3f;
		for (ll j = 1;j <= n;j++) minn = min(minn, dp[j][y]);
		minn += dis[y];
		// cout << dis[y] << endl;
		// cout << minn << endl;
		for (ll j = 1;j <= n;j++) {
			if (dp[j][x] < 0x3f3f3f3f3f3f3f3f) {
				dp[j][x] += min(minn, dp[j][y]);
			}
		}
	}
}
bool check(ll mid) {
	memset(can, 0, sizeof(can));
	lim = mid;
	for (ll i = 1;i <= n;i++) init(i, 0, i);
	dfs(1, 0);
	ll ans = 0x3f3f3f3f3f3f3f3f;
	for (ll i = 1;i <= n;i++) {
		ans = min(ans, dp[i][1]);
		// cout << dp[i][1] << " ";
	}
	// cout << endl;
	// cout << mid << " " << ans << endl;
	if (ans <= k) return 1;
	return 0;
}
//---------------------------------
int main() {
	// freopen("debug.in", "r", stdin);
	// freopen("debug.out", "w", stdout);
	n = read(), m = read(), k = read();
	ll l = 1000000000, r = 0;
	for (ll i = 1;i <= n;i++) h[i] = read(), l = min(l, h[i]), r = max(r, h[i]);
	for (ll i = 2;i <= n;i++) {
		ll x = read(), y = read();
		Add(x, y);
	}
	dfs1(1), dfs2(1, 1);
	for (ll i = 1;i <= m;i++) {
		ll x = read(), y = read();
		ll lca = LCA(x, y);
		d[x]++, d[y]++;
		d[lca] -= 2;
	}
	get_dis(1);
	ll ans = 0;
	l = 0;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (check(mid)) r = mid - 1, ans = mid;
		else l = mid + 1;
	}
	cout << ans << endl;
	return 0;
}
2023/7/26 19:43
加载中...