题目链接:http://poj.org/problem?id=2342
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6060 | Accepted: 3488 |
Description
Input
Output
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题意:有n个员工,每个员工都有一个权值(可为负)。然后有n-1条语句,每条两个数字i,j,表示j是i的上司。 从这几个人中选出几个人,要求相互之间不能有直接上下级关系,求最大的权值。注意可以一个人都不选,结果为0.
思路:一看就是树形DP,因为员工之间是一个树的关系。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 6050 #define minn -(1<<25) struct Tree { int val,next; } edge[N]; int flag[N],head[N]; int dp[2][N]; int cnt; void addedge(int s,int e) { edge[cnt].val=e; edge[cnt].next=head[s]; head[s]=cnt++; } void dfs(int node) { for(int i=head[node]; i!=-1; i=edge[i].next) { int val=edge[i].val; dfs(val); dp[1][node]=max(dp[1][node],dp[1][node]+dp[0][val]); dp[0][node]+=max(dp[1][val],dp[0][val]); } } int main() { int n,s,e,m; while(~scanf("%d %d",&n,&dp[1][1])&&(n+dp[1][1])) { cnt=0; for(int i=2; i<=n; i++) scanf("%d",&dp[1][i]); memset(head,-1,sizeof(head)); memset(flag,0,sizeof(flag)); memset(dp[0],0,sizeof(dp[0])); for(int i=1; i<n; i++) { scanf("%d %d",&e,&s); flag[e]=1; addedge(s,e); } for(int i=1; i<=n; i++) if(!flag[i]) { m=i; break; } memset(flag,0,sizeof(flag)); dfs(m); int maxn=minn; if(maxn<dp[1][m]) maxn=dp[1][m]; if(maxn<dp[0][m]) maxn=dp[0][m]; printf("%d\n",maxn); } return 0; }