[luogu P1352] 没有上司的舞会 (树形dp)

日常来道水题233
题目描述
某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入输出格式
输入格式:
第一行一个整数N。(1<=N<=6000)

接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

最后一行输入0 0

输出格式:
输出最大的快乐指数。

输入输出样例
输入样例#1:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出样例#1:
5

考虑每个人是否要来,传递一下就行

code:

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define f(a,b,c) for(int a=b;a<=c;a++)
using namespace std;

int rd() {
    int x=0,fla=1; char c=' ';
    while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
    while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
    return x*fla;
}

const int MAX=7010;
const int INF=0x3f3f3f3f;
int n,rt;
int du[MAX],f[MAX][2]; //1表示参加 0表示不参加 
vector <int> son[MAX];

void dfs(int x) {
    int num=son[x].size();
    f(i,0,num-1) {
        int y=son[x][i];
        dfs(y);//先递归再计算 
        f[x][0]+=max(f[y][0],f[y][1]);
        f[x][1]+=f[y][0];
    }
}

int main() {
    n=rd();
    f(i,1,n) f[i][1]=rd();
    f(i,1,n) {
        int a=rd(),b=rd();
        if(!a&&!b) continue;
        du[a]++;
        son[b].push_back(a);
    }

    f(i,1,n) if(!du[i]) { rt=i; break; }

    dfs(rt);
    printf("%d",max(f[rt][1],f[rt][0]));
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9247983.html