# 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 总结

• AngOn823
• 2016年08月27日 14:12
• 1628

## 树形DP—依赖背包模板

void DP(int x){ for(int i=0;i
• xlzhang223
• 2016年03月12日 12:25
• 235

## 树形DP总结，持续更新

• Dacc123
• 2016年01月03日 18:09
• 403

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

• txl16211
• 2015年04月29日 23:10
• 9845

## 树形动态规划（树形DP）入门问题—初探 & 训练

• txl16211
• 2015年04月29日 22:40
• 9951

## hdoj1561The more, The Better（树形dp，依赖背包）

• y990041769
• 2014年07月23日 17:57
• 3168

## 树形dp 小结

• Clove_unique
• 2016年11月17日 22:32
• 558

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

• xyqzki
• 2015年12月16日 22:08
• 823

## 树形dp学习

• carryheart
• 2016年09月27日 20:48
• 203

## 树形DP整理小结

• tomorrowtodie
• 2016年08月24日 15:38
• 981

举报原因： 您举报文章：hihocoder1104(Dfs预处理+树形DP) 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)