# hihocoder1104(Dfs预处理+树形DP)

## 题目描述

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.

## 算法思路

ans=dp[mi]+sum(i)

## 代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;

#define MAXN 105

int attr[MAXN],siz[MAXN];
vector<int>grid[MAXN];
vector<int>id;
bool isImportant[MAXN];
int n,k,m;
int dp[MAXN][MAXN];
int tongji[MAXN];

void Dfs1(int cur,int fa)
{//construct the subtree that we must visit
int i,j;
siz[cur] = 1;
//  printf("%d %d\n",cur,fa);

for(i=0;i<grid[cur].size();i++){
int dest = grid[cur][i];
if(dest!=fa){
Dfs1(dest,cur);
isImportant[cur] |= isImportant[dest];
}
}

if(isImportant[cur]){
for(i=0;i<grid[cur].size();i++){
int dest = grid[cur][i];
if(dest!=fa){
if(isImportant[dest]){
siz[cur] += siz[dest];
attr[cur] += attr[dest];
}
else
id.push_back(dest);
}
}
}
return;
}

void Dfs2(int cur,int fa)
{//construct the best answer via dynamic programming
int i,j,k;
siz[cur]=1;
dp[cur][1] = attr[cur];

for(i=0;i<grid[cur].size();i++){
int dest = grid[cur][i];
if(!isImportant[dest]&&dest!=fa){
Dfs2(dest,cur);
siz[cur] += siz[dest];
for(j=siz[cur];j>1;j--){
for(k=j-1;k>=0;k--){
dp[cur][j] = max(dp[cur][j],dp[cur][j-k]+dp[dest][k]);
}
}
}
}
return;
}

int main()
{
//freopen("input","r",stdin);
int i,j,k;
int tmp1,tmp2;

memset(isImportant,false,sizeof(isImportant));
memset(dp,0,sizeof(dp));
memset(tongji,0,sizeof(tongji));

scanf("%d%d%d",&n,&k,&m);

for(i=1;i<=n;i++)
scanf("%d",&attr[i]);

for(i=0;i<k;i++){
scanf("%d",&tmp1);
isImportant[tmp1] = true;
}

for(i=0;i<n-1;i++){
scanf("%d%d",&tmp1,&tmp2);
grid[tmp1].push_back(tmp2);
grid[tmp2].push_back(tmp1);
}

Dfs1(1,-1);

if(n<m||siz[1]>m)
printf("-1\n");
else{
m -= siz[1];
for(i=0;i<id.size();i++){
Dfs2(id[i],-1);
for(j=m;j>=0;j--){
for(k=j;k>=0;k--){
tongji[j] = max(tongji[j],tongji[k]+dp[id[i]][j-k]);
}
}
}
//printf("%d\n",attr[1]);
printf("%d\n",attr[1]+tongji[m]);
}
return 0;
}

#### 树形DP【最大利润】（转自jz_terry）

2017-07-11 19:28:35

#### 一、树形dp（4）有线电视网

2015-07-14 14:26:41

#### 2016 Multi-University Training Contest 2 1006 Fantasia （hdu5739） 【割点 无向图dfs树 树形dp】

2016-07-23 11:36:00

#### 一种利用重链剖分优化一类树形动态规划空间复杂度的方法

2017-04-12 22:08:06

#### 关于dfs和dp的思考

2014-09-16 16:36:19

#### 树形DP整理小结

2016-08-24 15:38:21

#### leetcode -- 解题总结--DP与DFS， 递归

2015-12-16 22:08:08

#### 树形动态规划（树状DP）小结

2015-04-29 23:10:03

#### 树形 DP 总结

2016-08-27 14:12:16

#### 华中科大2011状态压缩DP和树形DP

2018年05月15日 905KB 下载