上午看了想了好長時間,下午用了一個多小時才寫出來,主要對回溯沒怎麼寫過。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 }