标签:上传 content art mem break office arc esc first
要举办一个聚会,每个人都编号从1开始,每个人有一个快乐度,整个单位等级可看成一棵树,只有一个根,每个人不与上级或下级同时参加,即父亲和儿子不同时参加聚会,参加聚会后获得此人相应的快乐度,求最大快乐度。
树形dp,开数组dp[N][2],dp[i][j]——第i个人参加或不参加,j=0不参加,j=1参加。数组存下以当前人为根,下面所有人最大快乐度。
输入后先找根,然后从根开始dfs到最低层从下向上传值。
答案就是根节点的值。
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<vector> 5 #include<algorithm> 6 #define MAX 7000 7 using namespace std; 8 int a[6666]; 9 int dp[6666][3]; 10 struct node 11 { 12 int to,nex; 13 }edge[MAX*2+5]; 14 int head[MAX+5],cnt; 15 void add(int u,int v)//添加一个单向边u->v 权为w 16 { 17 edge[cnt].to=v; 18 edge[cnt].nex=head[u]; 19 head[u]=cnt++; 20 } 21 int ru[6666]; 22 void dfs(int t) 23 { 24 int i; 25 for(i=head[t];~i;i=edge[i].nex) 26 { 27 dfs(edge[i].to); 28 } 29 dp[t][0]=0; 30 dp[t][1]=a[t]; 31 for(i=head[t];~i;i=edge[i].nex) 32 { 33 dp[t][1]+=dp[edge[i].to][0]; 34 dp[t][0]+=max(dp[edge[i].to][1],dp[edge[i].to][0]); 35 } 36 } 37 int main() 38 { 39 int n; 40 while(cin>>n) 41 { 42 memset(head,-1,sizeof(head));//初始化为-1 43 cnt=0;//初始化 0 44 memset(dp,0,sizeof(dp)); 45 memset(ru,0,sizeof(ru)); 46 int i; 47 for(i=1;i<=n;i++) 48 { 49 scanf("%d",&a[i]); 50 } 51 int x,y; 52 while(scanf("%d%d",&x,&y),x&&y) 53 { 54 add(y,x); 55 ru[x]++; 56 } 57 int root; 58 for(i=1;i<=n;i++) 59 { 60 if(ru[i]==0) 61 { 62 root=i; 63 break; 64 } 65 } 66 dfs(root); 67 cout<<max(dp[root][1],dp[root][0])<<endl; 68 } 69 }
标签:上传 content art mem break office arc esc first
原文地址:http://www.cnblogs.com/jinmingyi/p/7306069.html