poj 2342 Anniversary party
没有上司的晚会
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
程序名:party
输入格式:
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出格式:
输出最大的快乐指数。
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输入样例:
5
来源:URAL
树形结构上的动态规划
设:
dp[i][0] 表示以i为根,i自己不参加party的最大快乐指数。
dp[i][1] 表示以i为根,i自己参加pary的最大快乐指数。
dp[i][0] = sigma( max(dp[j][0], dp[j][1]) ); j为i的子节点
dp[i][1] = sigma( dp[j][0] );
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int maxn = 10000; vector<int> G[maxn]; int fa[maxn], vis[maxn], val[maxn]; int dp[maxn][2]; int root; void dfs(int u) { vis[u] = 1; dp[u][0] = 0; dp[u][1] = val[u]; for(int i=0; i<G[u].size(); ++i) { int v = G[u][i]; if(!vis[v]) dfs(v); dp[u][0] += max(dp[v][0], dp[v][1]); dp[u][1] += dp[v][0]; } } int main() { int n, i, u, v; scanf("%d", &n); for(i=1; i<=n; ++i) scanf("%d", &val[i]); while(~scanf("%d%d", &u, &v)) { if(u==0 && v==0) break; fa[u] = v; G[v].push_back(u); } for(i=1; fa[i]; ++i); dfs(root=i); printf("%d\n", max(dp[root][0], dp[root][1])); return 0; }