URAL 1039 Anniversary Party 树形DP 水题

1039. Anniversary Party

Time limit: 0.5 second
Memory limit: 8 MB

Background

The president of the Ural State University is going to make an 80‘th Anniversary party. The university has a hierarchical structure of employees; that is, the supervisor relation forms a tree rooted at the president. Employees are numbered by integer numbers in a range from 1 to N, The personnel office has ranked each employee with a conviviality rating. In order to make the party fun for all attendees, the president does not want both an employee and his or her immediate supervisor to attend.

Problem

Your task is to make up a guest list with the maximal conviviality rating of the guests.

Input

The first line of the input contains a number N. 1 ≤ N ≤ 6000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality rating is an integer number in a range from –128 to 127. After that the supervisor relation tree goes. Each line of the tree specification has the form

<L> <K>

which means that the K-th employee is an immediate supervisor of L-th employee. Input is ended with the line

0 0

Output

The output should contain the maximal total rating of the guests.

Sample

input output
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
5

题意:一个公司有n个人,根据职位刚好组成一个树。

每一个人都有一个有趣值。

现在要从这n个人中邀请部分人去参加party,使得这个party的有趣值为最大。

但是有个要求:一个人和他的直属上司不能被同时邀请(不然就无趣了)

注意:根节点不固定,要根据数据确定。

     根节点可能不会被邀请。

树形DP水题。

dp[i][0]表示i不去的话以i为根的子树的最大的有趣值。

dp[i][1]表示i去的话以i为根的子树的最大的有趣值。

树形DP:

1.建树(链式前向星)

2.可能需要DFS预处理

3.递归求解dp

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
 5 using namespace std;
 6
 7 const int maxn=6010;
 8
 9 struct Edge
10 {
11     int to,next;
12 }edge[maxn];
13 int head[maxn];
14 int tot;
15 int dp[maxn][2];
16 int w[maxn];
17 int in[maxn];
18 int rt;
19
20 void init()
21 {
22     memset(head,-1,sizeof(head));
23     tot=1;
24     memset(dp,0,sizeof(dp));
25     memset(in,0,sizeof(in));
26 }
27
28 void addedge(int u,int v)
29 {
30     edge[tot].to=v;
31     edge[tot].next=head[u];
32     head[u]=tot++;
33 }
34
35 void tree_dp(int u,int fa)
36 {
37     dp[u][1]=w[u];
38     for(int i=head[u];~i;i=edge[i].next)
39     {
40         int v=edge[i].to;
41         if(v==fa)
42             continue;
43         tree_dp(v,u);
44         dp[u][1]+=dp[v][0];
45         dp[u][0]+=max(dp[v][0],dp[v][1]);
46     }
47 }
48
49 int main()
50 {
51     int n;
52     while(scanf("%d",&n)!=EOF)
53     {
54         init();
55         scanf("%d",&w[1]);
56         if(n==0&&w[1]==0)
57             break;
58         for(int i=2;i<=n;i++)
59             scanf("%d",&w[i]);
60         for(int i=1;i<n;i++)
61         {
62             int u,v;
63             scanf("%d%d",&v,&u);
64             addedge(u,v);
65             in[v]++;
66         }
67         for(int i=1;i<=n;i++)
68             if(in[i]==0)
69             {
70                 rt=i;
71                 break;
72             }
73
74         tree_dp(rt,-1);
75
76         int ans=max(dp[rt][0],dp[rt][1]);
77         printf("%d\n",ans);
78     }
79     return 0;
80 }

时间: 2024-10-05 04:58:17

URAL 1039 Anniversary Party 树形DP 水题的相关文章

POJ 2342 &amp;&amp;HDU 1520 Anniversary party 树形DP 水题

一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点)都不能被邀请 2.每一个员工都有一个兴奋值,在满足1的条件下,要使得邀请来的员工的兴奋值最高 输出最高的兴奋值. 简单的树形DP dp[i][1]:表示以i为根的子树,邀请节点i的最大兴奋值 dp[i][0]:表示以i为根的子树,不邀请节点i的最大兴奋值 先根据入度找出整棵树的根节点, 然后一次DF

HDU 1520 Anniversary party 树DP水题

非常水的树DP,状态为当前为i,上级来没来 然后跑一遍记忆化搜索即可 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib>

洛谷P1352 没有上司的舞会(树形DP水题)

题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了.所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数. 输入输出格式 输入格式: 第一行一个整数N.(1<=N<=6000) 接下来N行,第i+1行表示i号职员的快乐指数Ri.(-128<=Ri

树形DP水题系列(1):FAR-FarmCraft [POI2014][luogu P3574]

题目 大意: 边权为1 使遍历树时到每个节点的时间加上点权的最大值最小 求这个最小的最大值 思路: 最优化问题 一眼树形DP 考虑状态设立 先直接以答案为状态 dp[u] 为遍历完以u为根的子树的答案 再考虑状态转移 dp[u]=MAX(dp[to]+1,siz+dp[to]);siz为枚举子树到以to为节点的子树时之前已遍历的总时间 很明显这个转移过来的dp值的最优化依赖于子树遍历的顺序 所以我们需要找到一种最优的子树遍历顺序来使每个子树得到最优的dp值来更新 我们通过观察可以发现 交换任意两

POJ 2342 Anniversary party (树形dp 入门题)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4810   Accepted: 2724 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

hdu1520Anniversary party 树形dp水题

/* dp[i][0]表示第i个人不去的时候能得到的最大值 dp[i][1]表示第i个人去的时候得到的最大值 状态转移方程: dp[i][0]+=max(dp[next][0],dp[next][1]) dp[i][1]+=dp[next][0] 其中next为其子节点 */ #include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std;

树形DP水题杂记

BZOJ1131: [POI2008]Sta 题意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大. 题解:记录每个点的深度,再根据根节点的深度和逐层推导出其他点的深度和. 我用的是BFS #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; typedef long long ll; int

POJ 2342 Anniversary party 树形DP基础题

题目链接:http://poj.org/problem?id=2342 题目大意:在一个公司中,每个职员有一个快乐值ai,现在要开一个party,邀请了一个员工就不可能邀请其直属上司,同理邀请了一个人就不可以邀请其的直属员工, 问如何使得这个快乐值达到最大. 题解:对每个结点dp[i][0]表示不邀请这个员工,其子树达到的最大快乐值,dp[i][1]表示邀请i员工其子树达到的最大值. dp[i][0]=(i的全部员工的max(dp[u][1],dp[u][0)相加,也就是其子员工来或不来的最大快

树形DP URAL 1039 Anniversary Party

题目传送门 1 /* 2 题意:上司在,员工不在,反之不一定.每一个人有一个权值,问权值和最大多少. 3 树形DP:把上司和员工的关系看成根节点和子节点的关系,两者有状态转移方程: 4 dp[rt][0] += max (dp[son][1], dp[son][0]); //上司不去 5 dp[rt][1] += dp[son][0]; //上司去,员工都不去 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <