Suzhou Adventure,hihocoder 1104

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

Little Hi is taking an adventure in Suzhou now. There are N beautiful villages in Suzhou which are numbered from 1 to N. They connected by N-1 roads in such a way that there is excactly one way to travel from one village to another. Little Hi gives each village a score according to its attractiveness. He is visiting village 1 now and plans to visit excatly M villages (including village 1) and maxize the total score of visited villages. Further more, K villages are recommended by Little Ho. He does not want to miss these recommended villages no matter what their attractiveness scores are.

Note that Little Hi visits every village on his travel route. Passing a village without visiting it is not allowed. Please find the maximum total score Little Hi can get.

输入

The first line contains 3 integers N(1 <= N <= 100), K(1 <= K <= 5) and M(1 <= M <= N), representing the number of villages, the number of recommended villages and the number of villages Little Hi plans to visit.
The second line contains N integers, the attractiveness scores of villages. The scores are between 1 to 100.
The third line contains K integers, the list of recommended villages.
The following N-1 lines each contain two integers a and b, indicating that village a and village b are connected by a road.

输出

The maximum scores Little Hi can get. If there is no solution output -1.

样例输入
5 2 4
1 2 3 4 5
3 4
1 2
1 3
1 4
2 5
样例输出
10

解法:树形DP,对于一定要参观的地方,将它的吸引值设置成INF(就是比所以的吸引值的和还要大一点),这样一定要参观某些景点的限制就没有了。
dp[i][j]:根节点在i,包含j个点的子树的最大吸引值。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 struct node{
 7     int to;
 8     int next;
 9 }e[300];
10 int act[102];
11 int dp[102][102];
12 int n,k,m;
13 int ct;
14 int h[102];
15 void dfs(int x,int fa){
16     
17     for(int i=h[x];i;i=e[i].next)
18       if(e[i].to!=fa)    dfs(e[i].to,x);
19     dp[x][1]=act[x];
20     for(int i=h[x];i;i=e[i].next){
21         int v=e[i].to;
22         if(v!=fa){
23             for(int j=m;j>1;j--){
24                 for(int k=1;k<j;k++)
25                 dp[x][j]=max(dp[x][j-k]+dp[v][k],dp[x][j]);
26             }
27         }
28     }
29       
30 }
31 
32 void input(){
33     cin>>n>>k>>m;
34     for(int i=1;i<=n;i++)cin>>act[i];
35     int t;
36     int tm=0;
37     for(int i=0;i<k;i++)cin>>t,tm+=act[t],act[t]=20000;
38     int u,v;
39     ct=1;
40     for(int i=1;i<n;i++){
41         cin>>u>>v;
42         e[ct].to=u;e[ct].next=h[v];
43         h[v]=ct++;
44         e[ct].to=v;e[ct].next=h[u];
45         h[u]=ct++;        
46     } 
47     dfs(1,0);
48     if(dp[1][m]>=k*20000){
49         cout<<dp[1][m]-k*20000+tm<<endl;
50     }else cout<<-1<<endl;
51 }
52 
53 int main(int argc, char** argv) {
54     input();
55     return 0;
56 }
原文地址:https://www.cnblogs.com/zhjou/p/4734995.html