P2286 [HNOI2004]宠物收养场

第一次用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;
}
posted @ 2018-08-09 14:19  Garen-Wang  阅读(164)  评论(0编辑  收藏  举报