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;
}

猜你喜欢

转载自www.cnblogs.com/Garen-Wang/p/9448652.html