牛客2022多校DAY10-K You are given a tree
「牛客2022多校DAY10-K」 You are given a tree...
简要题意
给一棵带点权和边权的树,找到至多
Solution
考虑颜色数量不大的时候怎么暴力。显然可以直接状压 DP,压一下当前选择的颜色集合为
注意到
原来的
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace Hanx16qwq {
constexpr int _N = 5e3 + 5;
int n, k, a[_N], b[_N], col[_N];
struct EDGE{int nxt, to, l;} edge[_N << 1];
int tot, head[_N];
void AddEdge(int x, int y, int l) {
edge[++tot] = {head[x], y, l};
head[x] = tot;
}
int f[_N][64], temp[64], maxn, ans = INT_MIN;
void DfsForAns(int x, int fa) {
f[x][0] = f[x][1 << col[x]] = 0;
for (int i = head[x]; i; i = edge[i].nxt) {
int twd = edge[i].to;
if (twd == fa) continue;
DfsForAns(twd, x);
memcpy(temp, f[x], sizeof f[x]);
for (int s = 1; s < maxn; s++)
for (int ss = s; ss; ss = (ss - 1) & s)
if (ss != (maxn - 1))
f[x][s] = max(f[x][s], temp[s ^ ss] + f[twd][ss] + edge[i].l);
}
ans = max(ans, f[x][maxn - 1]);
}
mt19937 rnd(114514);
void main() {
cin >> n >> k; maxn = 1 << k;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1, u, v, l; i < n; i++) {
cin >> u >> v >> l;
AddEdge(u, v, l);
AddEdge(v, u, l);
}
int Times = 200;
while (Times--) {
for (int i = 1; i <= n; i++) b[i] = rnd() % k;
for (int i = 1; i <= n; i++) col[i] = b[a[i]];
memset(f, 0xcf, sizeof f);
DfsForAns(1, 0);
}
cout << ans << '\n';
}
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
Hanx16qwq::main();
return 0;
}
分类:
标签:
,
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步