树形dp poj 2342

上午看了想了好长时间,下午用了一个多小时才写出来,主要对回溯没怎么写过。ios

第一题 树形dp。ide

题意就是有关系的两我的不能同时出现。spa

dp1【s】 表示 s点去。code

dp2【s】 表示s点不去。blog

dp1【s】+=dp2【x】。 //s点去,ze x点不去    (s为父节点)。string

dp2【s】+=max(dp1【x】,dp2【x】);// s点不去,则x去或不去的最大的一个it

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<vector>
 5 using namespace std;
 6 vector<int>V[6006];
 7 int vis[6006];
 8 int dp1[6006];//
 9 int dp2[6006];//不去
10 void init()
11 {
12     for(int i=0;i<6005;i++)
13       V[i].clear();
14     memset(dp1,0,sizeof(dp1));
15     memset(dp2,0,sizeof(dp2));
16     memset(vis,0,sizeof(vis));
17 }
18 void dfs(int s)
19 {
20     vis[s]=1;
21     for(int i=0;i<(int)V[s].size();i++)
22     {
23         int x=V[s][i];
24         if(!vis[x])
25         {
26             dfs(x);
27             dp1[s]+=dp2[x];   //s去,则x不去。
28             dp2[s]+=max(dp1[x] , dp2[x]);   //s不去,则在s点加上x去或不去的最大值.
29             //printf("dp1[%d]=%d   dp2[%d]=%d\n",s,dp1[s],s,dp2[s]);
30         }
31     }
32 }
33 int main()
34 {
35     //freopen("Input.txt","r",stdin);
36     int n,i;
37     while(~scanf("%d",&n))
38     {
39         init();
40         for(i=1;i<=n;i++)
41         {
42             scanf("%d",&dp1[i]);
43             dp2[i]=0;
44         }
45         int a,b;
46         while(scanf("%d%d",&a,&b)!=EOF)
47         {
48             if(a==0&&b==0) break;
49             V[a].push_back(b);
50             V[b].push_back(a);
51         }
52         for(i=1;i<n;i++)
53         {
54             if(vis[i]==0)
55             dfs(i);
56         }
57         int res=max(dp1[1],dp2[1]);
58         printf("%d\n",res);
59     }
60     return 0;
61 }
代码
相关文章
相关标签/搜索