没有上司的舞会(树形dp裸题)

来源:互联网 发布:mac上的邮箱软件 编辑:程序博客网 时间:2024/05/21 11:30

题目 >>http://codevs.cn/problem/1380/

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int MAXN = 2e5;bool used[MAXN];int n,a,b,num[MAXN],s,firs[MAXN],ans,nex[MAXN],dp[MAXN][2],cnt = 0;struct zt{    int f,t;}road[MAXN];void build(int f,int t){    road[++cnt] = (zt){f,t};    nex[cnt] = firs[f];    firs[f] = cnt;}int dfs(int x,int d) //表示x 去(d == 1)还是不去(d == 0)。 {    int ans = 0;    for(int i = firs[x];i != -1; i = nex[i])    {        int v = road[i].t;        if(!dp[v][0])            dp[v][0] = dfs(v,0); // 记忆化,表示该状态下dp[编号][去与否]的最大值         if(!dp[v][1])            dp[v][1] = dfs(v,1);        if(d)            ans += dp[v][0]; //上司去。         else            ans += max(dp[v][0],dp[v][1]);//上司不去,若其下有更优解他也可能不去。     }    if(d)        return ans + num[x];//x 若去要加上他自己。     return ans;}int main(){    scanf("%d",&n);    for(int i = 1;i <= n; i++)        scanf("%d",&num[i]),firs[i] = -1;    for(int i = 1;i < n; i++)    {        scanf("%d%d",&a,&b);        build(b,a); // 建立上下级关系的图         used[a] = 1;    }    scanf("%d%d",&a,&b);    for(int i = 1;i <= n;i ++)        if(!used[i])        {            s = i; //找到大boss(根节点)。            break;        }    ans = max(dfs(s,0),dfs(s,1)); // 分别计算大boss去还是不去。     printf("%d",ans);} 
原创粉丝点击