CodeForces 77C Beavermuncher-0xFF

不错的树形dp。一个结点能走多次,树形的最大特点是到达后继的路径是唯一的,那个如果一个结点无法往子结点走,那么子结点就不用考虑了。

有的结点不能走完它的子结点,而有的可能走完他的子节点以后还会剩下一些点数。影响走的次数的是当前结点的点数,因为往子结点走是一定要回来的,进入这个结点要花费这个结点一个点数,剩下的点数就是往子结点走的最大次数,但是有可能会有剩余的点数。可以这样处理,定义一个dp[i]表示花费一个点数进入i结点以后从它及其后代得到的最大价值,根据这个定义,能走到的结点i的dp[i]至少为1,而且花费为1,如果有剩下的点数,对于i的父节点,想要得到剩下的点数,花费一个1点数才能得到1个点数,不会比dp[i]更优,所以优先考虑选择dp[i],对于同样的dp值优先选大的。

转移方程为dp[i] = {dp[j]}+cnt*2,|{dp[j]}|==min(k[i]-1,|{j}|),|{j}|表示后代点数,

当k[i]-1>|{j}|时可以选完后代的dp值,然后就要考虑选剩下的点数,

cnt是子节点后剩下的点数和后代结点剩下的点数的最小值,cnt = min(k[u]-1-|{j}|,sum(left(j)))。left(j)是j计算完dp[j]后剩下的点数。

转移的时候还要维护一下left(i)。不能走到的点就不考虑了。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
typedef long long ll;

int k[maxn];
ll d[maxn];

vector<int> G[maxn];
#define PB push_back

bool cmp(int a,int b) { return a > b; }
ll dp(int u,int fa)
{
    if(d[u]>0) return d[u];
    k[u]--;
    if(!G[u].size()|| !k[u]) {
        return d[u] = 1;
    }
    vector<ll> opt;
    int cnt = 0;
    for(int i = 0; i < (int)G[u].size(); i++){
        int v = G[u][i];
        if(v == fa || !k[v]) continue;
        opt.PB(dp(v,u));
        cnt += k[v];
    }
    if(!opt.size()) return d[u] = 1;
    int m = min(k[u],(int)opt.size());
    nth_element(opt.begin(),opt.begin()+m,opt.end(),cmp);
    k[u] -= m;
    d[u] = m;
    for(int i = 0; i < m; i++){
        d[u] += opt[i];
    }
    if(k[u]>0){
        m = min(k[u],cnt);
        k[u] -= m;
        d[u] += m<<1;
    }
    return ++d[u];
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n; scanf("%d",&n);
    for(int i = 1; i <= n; i++) scanf("%d",k+i);
    for(int i = 1; i < n; i++){
        int u,v; scanf("%d%d",&u,&v);
        G[u].PB(v); G[v].PB(u);
    }
    int s; scanf("%d",&s);
    k[s]++;
    printf("%I64d\n",dp(s,-1)-1);
    return 0;
}
时间: 2024-11-05 14:15:54

CodeForces 77C Beavermuncher-0xFF的相关文章

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

CodeForces 23E ,77C,455A,437E,245H

五天每天刷了一dp CodeForces 455A Boredom   定义 :dp[i]为取前i个元素后得到的最大值.则dp[i]=max(dp[i-1],dp[i-2]+a[i]*i); 写的时候愚蠢的分类讨论i元素是否选取.实际上第i-2个元素是否选取和状态dp[i]无关 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define ll __int64 co

Codeforces Round #259 (Div. 2) 解题报告

终于重上DIV1了.... A:在正方形中输出一个菱形 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月01日 星期五 23时27分55秒 4 5 #include<vector> 6 #include<set> 7 #include<deque> 8 #include<stack> 9 #include<bitset> 10 #inclu

codeforces:Prefix Sums

题目大意: 给出一个函数P,P接受一个数组A作为参数,并返回一个新的数组B,且B.length = A.length + 1,B[i] = SUM(A[0], ..., A[i]).有一个无穷数组序列A[0], A[1], ... 满足A[i]=P(A[i-1]),其中i为任意自然数.对于输入k和A[0],求一个最小的下标t,使得A[t]中包含不小于k的数值. 其中A[0].length <= 2e5, k <= 1e18,且A[0]中至少有两个正整数. 数学向的题目.本来以为是个找规律的题目

codeforces:Helga Hufflepuff&#39;s Cup

题目大意:有一个包含n个顶点的无向无环连通图G,图中每个顶点都允许有一个值type,type的范围是1~m.有一个特殊值k,若一个顶点被赋值为k,则所有与之相邻的顶点只能被赋小于k的值.最多有x个顶点被赋值为k.求问有多少种不同的赋值方案. 这是一道树形DP的题目.由于是无环无向连通图,因此可以任选一个顶点R作为根结点,从而构造一颗树TREE.为每个顶点N维护一个属性maybe[3][x+1].其中maybe[0][i]表示当N被赋小于k的值时,N及其所有后代结点总共出现i个被赋值为k的结点的总

codeforces:855D Rowena Ravenclaw&#39;s Diadem分析和实现

题目大意: 提供n个对象,分别编号为1,...,n.每个对象都可能是某个编号小于自己的对象的特例或是成分.认为某个对象的特例的特例依旧是该对象的特例,即特例关系传递,同样一个对象的成分的成分依旧是该对象的成分.但是还需要注意一个对象的成分是该对象的所有特例的成分.每个对象都不可能是自己的特例或成分.要求解答之后的q个谜题,每个谜题提问两个对象是否是特例关系或成分关系. 输入级别:n,q<1e5 花了一个晚上才想到思路解了题目... 首先我们要先解决一个简单的问题,我将这道题目这样描述,对于一株多

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th