codevs 1380 没有上司的舞会 - 树形动态规划

题目描述 Description

Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。

输入描述 Input Description

第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。

输出描述 Output Description

输出最大的快乐指数。

样例输入 Sample Input

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

样例输出 Sample Output

5 

数据范围及提示 Data Size & Hint

各个测试点1s



  按照这个关系建一棵树,然后进行树归,用f[i]表示i职员参加舞会的最大快乐指数之和,g[i]表示i职员不参加舞会的最大快乐指数之和。那么有f[i]为所有i的子节点的g[son[i]]的和,g[i]是i的子节点的g[son[i]]和f[son[i]]最大值的和。

  最后的答案在f[1]和g[1]中找最大值。

Code

  1 /**
  2  * codevs
  3  * Problem#1380
  4  * Accepted
  5  * Time:10ms
  6  * Memory:492k
  7  */
  8 #include<iostream>
  9 #include<sstream>
 10 #include<algorithm>
 11 #include<cstdio>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<cctype>
 15 #include<cmath>
 16 #include<ctime>
 17 #include<map>
 18 #include<stack>
 19 #include<set>
 20 #include<queue>
 21 #include<vector>
 22 #ifndef WIN32
 23 #define AUTO "%lld"
 24 #else
 25 #define AUTO "%I64d"
 26 #endif
 27 using namespace std;
 28 typedef bool boolean;
 29 #define inf 0xfffffff
 30 #define smin(a, b) (a) = min((a), (b))
 31 #define smax(a, b) (a) = max((a), (b))
 32 template<typename T>
 33 inline boolean readInteger(T& u) {
 34     char x;
 35     int aFlag = 1;
 36     while(!isdigit((x = getchar())) && x != ‘-‘ && x != -1);
 37     if(x == -1)    {
 38         ungetc(x, stdin);
 39         return false;
 40     }
 41     if(x == ‘-‘) {
 42         aFlag = -1;
 43         x = getchar();
 44     }
 45     for(u = x - ‘0‘; isdigit((x = getchar())); u = u * 10 + x - ‘0‘);
 46     u *= aFlag;
 47     ungetc(x, stdin);
 48     return true;
 49 }
 50
 51 typedef class Edge {
 52     public:
 53         int end;
 54         int next;
 55         Edge(const int end = 0, const int next = 0):end(end), next(next) {        }
 56 }Edge;
 57
 58 typedef class MapManager {
 59     public:
 60         int ce;
 61         int *h;
 62         Edge *edge;
 63         MapManager():ce(0), h(NULL), edge(NULL)    {    }
 64         MapManager(int points, int edges):ce(0)    {
 65             h = new int[(const int)(points + 1)];
 66             edge = new Edge[(const int)(edges + 1)];
 67             memset(h, 0, sizeof(int) * (points + 1));
 68         }
 69
 70         inline void addEdge(int from, int end) {
 71             edge[++ce] = Edge(end, h[from]);
 72             h[from] = ce;
 73         }
 74
 75         Edge& operator [](int pos) {
 76             return edge[pos];
 77         }
 78 }MapManager;
 79 #define m_begin(g, i) (g).h[(i)]
 80
 81 int n;
 82 int *val;
 83 MapManager g;
 84 int *f, *g1;
 85 int root;
 86
 87 inline void init() {
 88     readInteger(n);
 89     val = new int[(const int)(n + 1)];
 90     g = MapManager(n, n);
 91     f = new int[(const int)(n + 1)];
 92     g1 = new int[(const int)(n + 1)];
 93     for(int i = 1; i <= n; i++)
 94         readInteger(val[i]);
 95     int sum = 0;
 96     for(int i = 1, a, b; i < n; i++) {
 97         readInteger(a);
 98         readInteger(b);
 99         sum += a;
100         g.addEdge(b, a);
101     }
102     root = n * (n + 1) / 2 - sum;
103 }
104
105 void treedp(int node, int fa) {
106     g1[node] = 0;
107     f[node] = val[node];
108     for(int i = m_begin(g, node); i != 0; i = g[i].next) {
109         int& e = g[i].end;
110         if(e == fa)    continue;
111         treedp(e, node);
112         g1[node] += max(g1[e], f[e]);
113         f[node] += g1[e];
114     }
115 }
116
117 inline void solve() {
118     treedp(root, 0);
119     printf("%d", max(g1[root], f[root]));
120 }
121
122 int main() {
123     init();
124     solve();
125     return 0;
126 }
时间: 2024-12-24 22:16:13

codevs 1380 没有上司的舞会 - 树形动态规划的相关文章

wikioi 1380 没有上司的舞会 树形dp

1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个快乐指数.现在有个周年庆宴会,要求与会职员的快乐指数最大.但是,没有职员愿和直接上司一起与会. 输入描述 Input Description 第一行一个整数N.(1<=N<=6000) 接下来N行,第i+1行表示

codevs 1380 没有上司的舞会

基本树型dp.dp[i][j]中i表示某人,j表示该人来了没来.转移方程见程序. 注意预处理:先初始化所有dp[i][1]为给定的权值.先将没有下属的人进队. #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,r[6005],fath[6005],num[6005]; int dp[6005][3]; void bf

1380 没有上司的舞会

1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个快乐指数.现在有个周年庆宴会,要求与会职员的快乐指数最大.但是,没有职员愿和直接上司一起与会. 输入描述 Input Description 第一行一个整数N.(1<=N<=6000)接下来N行,第i+1行

P1352 没有上司的舞会——树形DP入门

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

[luogu]P1352 没有上司的舞会[树形DP]

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

【luogu1352】没有上司的舞会 - 树形dp

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

没有上司的舞会 树形DP

题意:有n个职员可以参加舞会,每个职员有一个欢乐值,职员之间就像一颗树,每个父节点都是子节点的上司,同时一个职员不可以他的直接上司一起参加,.现在选一些员工参加舞会,求参加员工的可能最大快乐值. 做法:设f[i][0]表示i代表的子树之下,i职员不参加的最大快乐值,f[i][1]表示i代表的子树之下,i职员参加的最大快乐值.则状态转移方程得 f[i][0]+=max(f[j][1],f[i][0])如果i不参加,那么他的每个儿子j可以选择参加或者不参加,累加每个儿子的较大的值. f[i][1]+

poj2342 没有上司的舞会 树形dp基础

#include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; int n,dp[6050][2],flag[6050],h[6050]; vector<int> son[6050]; void dfs(int u){ dp[u][0]=0; dp[u][1]=h[u]; for(int i=0;i<son[u].size

codevs1380 没有上司的舞会

1380 没有上司的舞会 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个快乐指数.现在有个周年庆宴会,要求与会职员的快乐指数最大.但是,没有职员愿和直接上司一起与会. 输入描述 Input Description 第一行一个整数N.(1<=N<=6000)接下来N行,第i+1行表示i号职员的快乐指数Ri.(-128<=Ri<=127)接下来N-1行,每行输入