第一次用set水splay好爽啊!
这道题很明显,就是弄两个平衡树(一个也可以)。
进来一个人,就去另一边找找前驱和后继,优先找前驱,找个绝对值最小的配对走。
其实用一下set就可以了啊!
使用std::set.lower_bound
就可以找到x元素,--一下就得到前驱,++一下应该就得到了后继。
其实后继也直接可用upper_bound
。
再根据题意模拟一下就能过了。。。
这道题数据特别水。。。
代码:
#include<cstdio>
#include<algorithm>
const int maxn = 1005;
struct Edges
{
int next, to, weight;
} e[maxn];
int head[maxn], tot;
int dp[maxn][maxn];
int n, m;
void link(int u, int v, int w)
{
e[++tot] = (Edges){head[u], v, w};
head[u] = tot;
}
int dfs(int u)
{
int ans = 0;
for(int i = head[u]; i; i = e[i].next)
{
int v = e[i].to;
int t = dfs(v);
ans = ans + t + 1;
for(int j = std::min(ans, m); j > 0; j--)
{
for(int k = std::min(j - 1, ans); k > 0; k--)
{
dp[u][j] = std::max(dp[u][j], dp[u][j - k - 1] + dp[v][k] + e[i].weight);
}
}
}
return ans;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i < n; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
link(u, v, w);
}
dfs(1);
printf("%d\n", dp[1][m]);
return 0;
}