码迷,mamicode.com
首页 > 其他好文 > 详细

VK Cup 2015 - Round 2 B. Work Group

时间:2016-10-28 15:24:45      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:ret   ack   main   log   str   构建   max   题解   nbsp   

题解:

树形dp

首先开始做时我以为只要贪心选取就可以了...

后来发现根节点可以不用选,而选和为奇数的满足条件的子节点.

所以需要重新构建状态

dp[u][0]表示满足条件的以u为根节点的子树中,节点数为偶数的最大值

dp[u][0]表示满足条件的以u为根节点的子树中,节点数为奇数的最大值

最开始不选根节点.dp[u][0]=0,dp[u][1]为-INF(不存在)

每次加子节点v时

1.偶可以由偶(u)+偶(v),奇(u)+奇(v)更新

2.奇可以由奇(u)+奇(v),奇(u)+奇(v)更新

最后当子节点条件完后,所有子节点的和为偶的情况可以加上根节点

dp[u][1]=max(dp[u][1],dp[u][0]+1);

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=200005;
const int mod=1000000007;
int n,x;
int w[maxn];
ll dp[maxn][2];
vector<int> s[maxn];

void dfs(int u)
{
    dp[u][0]=0;dp[u][1]=-(1LL<<60);
    for(int i=0;i<s[u].size();i++)
    {
        int v=s[u][i];
        dfs(v);
        ll t0=dp[u][0],t1=dp[u][1];
        t0=max(t0,dp[u][0]+dp[v][0]);
        t0=max(t0,dp[u][1]+dp[v][1]);
        t1=max(t1,dp[u][1]+dp[v][0]);
        t1=max(t1,dp[u][0]+dp[v][1]);
        dp[u][0]=t0;
        dp[u][1]=t1;
    }
    dp[u][1]=max(dp[u][1],dp[u][0]+w[u]);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&w[i]);
        if(x==-1) continue;
        s[x].push_back(i);
    }
    dfs(1);
    printf("%lld\n",max(dp[1][0],dp[1][1]));
    return 0;
}

 

VK Cup 2015 - Round 2 B. Work Group

标签:ret   ack   main   log   str   构建   max   题解   nbsp   

原文地址:http://www.cnblogs.com/byene/p/6007839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!