HDU 4340 树形DP

【题意】:

给你一张无向图,无向图上每个点代表一个城市,有两个值Va,Vb,分别代表a,b占领该城市所需要消耗的时间,而且a或b去占领它们已经占领的城市的相领城市所需的花费为标准的一般。问最少需要花费多少钱。

【知识点】:

树形DP

【题解】:
dp[u][i][0]:代表以u为根的子树中没有一个点为颜色i绘画开始点所需的最小花费,
即字数中画有i颜色的点的代价都为原来的一般
dp[u][i][1]:代表以u为根的子树中有一个点为颜色i绘画开始点所需的最小花费
u的子树中涂i色的点中有一个点为其本身的代价而不是其一半

【代码】:

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4 #include <ctime>
 5 #include <queue>
 6 #include <stack>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstring>
11 #include <sstream>
12 #include <iostream>
13 #include <algorithm>
14 #include <bitset>
15 #include <climits>
16 using namespace std;
17
18 #define wh while
19 #define inf (int)(~0u/2)
20 #define FOR(i, n) for(int i = 0; i < n; i++)
21 #define FOR1(i, n) for(int i = 1; i < n; i++)
22 #define FOR2(i, n) for(int i = 0; i <= n; i++)
23 #define REP(i,n) for(int i = 1; i <= n; i++)
24 #define FORI(it,n) for(typeof(n.begin()) it = n.begin(); it != n.end(); it++)
25 #define sf scanf
26 #define pf printf
27 #define frs first
28 #define sec second
29 #define psh push_back
30 #define mkp make_pair
31 #define PB(x) push_back(x)
32 #define MP(x, y) make_pair(x, y)
33 #define clr(abc,z) memset(abc,z,sizeof(abc))
34 #define lt(v) v << 1
35 #define rt(v) v << 1 | 1
36 //#define mid ((l + r) >> 1)
37 #define lson l, mid, v << 1
38 #define rson mid + 1, r, v << 1 | 1
39
40 #define fre freopen("1.txt", "r", stdin)
41
42 typedef long long LL;
43 typedef long double LD;
44 const int INF = 0x3F3F3F3F;
45 const int maxn = 120;
46 vector<int> G[maxn];
47 int dp[maxn][2][2];
48 int cost[maxn][2]; int N;
49
50 void dfs(int u, int fa){
51     if(G[u].size() == 1 && fa != 0){
52         FOR(i, 2){
53             dp[u][i][0] = cost[u][i] / 2;
54             dp[u][i][1] = cost[u][i];
55         }
56         return ;
57     }
58     FOR(i, (int)G[u].size()){
59         int v = G[u][i];
60         if(v == fa) continue;
61         dfs(v, u);
62     }
63     FOR(i, 2){
64         int sum = 0, cha = INF;
65         int cst = cost[u][i];
66         FOR(j, (int)G[u].size()){
67             int v = G[u][j];
68             if(v == fa) continue;
69             int tmp = min(dp[v][i][0], dp[v][i ^ 1][1]); sum += tmp;
70             cha = min(cha, dp[v][i][1] - tmp);
71             //将原先选中的dp[v][i][0]或dp[v][i ^ 1][1]替换成dp[v][i][1]所需要的最小代价
72         }
73         dp[u][i][0] = cst / 2 + sum;
74         dp[u][i][1] = min(cst + sum, cst / 2 + sum + cha);
75     }
76 }
77
78 int main() {
79     wh(sf("%d", &N) != EOF){
80         REP(i, N) G[i].clear();
81         REP(i, N) sf("%d", &cost[i][0]);
82         REP(i, N) sf("%d", &cost[i][1]);
83         REP(i, N - 1){
84             int u, v; sf("%d%d", &u, &v);
85             G[u].PB(v); G[v].PB(u);
86         }
87         dfs(1, 0);
88         pf("%d\n", min(dp[1][0][1], dp[1][1][1]));
89     }
90 }

时间: 2024-12-19 10:01:40

HDU 4340 树形DP的相关文章

hdu 4123 树形DP+RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=4123 Problem Description Bob wants to hold a race to encourage people to do sports. He has got trouble in choosing the route. There are N houses and N - 1 roads in his village. Each road connects two houses,

hdu 1250 树形DP

Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-27) Description There is going to be a party to celebrate the 80-th Anniversary of the Ural St

hdu 4276(树形dp)

题意:带权树上有起点终点每个点上有宝藏,一个人只有T分钟要从起点到重点,问你最多能收集多少宝藏. 思路:树形dp,首先判断能不能走到终点,然后把路径上的边权变为0时间减去所有边权.dp[v][j]表示从v出发回到v话费j分钟最多能收集到的宝藏. dp[v][j] = max(dp[v][j], dp[x][k] + dp[v][j-k-2*val]); 被G++卡了好长时间,换成c++就过了. 代码如下: 1 #include <stdio.h> 2 #include <string.h

hdu 5148 树形dp+分组背包问题

http://acm.hdu.edu.cn/showproblem.php?pid=5148 Problem Description Long long ago,there is a knight called JayYe.He lives in a small country.This country is made up of n cities connected by n-1 roads(that means it's a tree).The king wants to reward Ja

HDU 1520 树形dp裸题

1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using nam

hdu 3586 树形dp+二分

题目大意:给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵 树,每条边都有一个权值cost表示破坏这条边的费用,叶子节点为前线.现要切断前线和司令部的联系,每次切断边的费用不能超过上限limit,问切断所 有前线与司令部联系所花费的总费用少于m时的最小limit.1<=n<=1000,1<=m<=100万 题目要问的是最小的最大限制,必然二分答案 然后对于每一个值,树形DP判定是否可行 dp[i]表示要切断以i为根的其它所有子树的最小代价. 其中设定叶子结点的代价为无穷大

HDU 1561 树形DP入门

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6011    Accepted Submission(s): 3555 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物

hdu 1561 树形dp

又一道树形dp,发现其实树形dp长得都挺像的. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = -9999999; 7 const int N = 201; 8 int dp[N][N]; 9 int head[N]; 10 int value[N]; 11 int n, m, e; 12 13 void i

hdu 1011 树形dp+背包

题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士兵可以得到的最大价值是多少 分析:树形dp,对于点u,dp[u][j]表示以u为根的树消耗j个士兵得到的最大值,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k]+val[u]) 注意是无向图,vis位置不能随便放,且注意dp不能直接+val,因为这样根节点就加不