标签:
<L> <K>
0 0
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 }
URAL 1039 Anniversary Party 树形DP 水题
标签:
原文地址:http://www.cnblogs.com/-maybe/p/4545225.html