樹形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 }
代碼
相關文章
相關標籤/搜索