hdu 4340 Capturing a country(树形 dp) (2012 Multi-University Training Contest 5 )
2012-08-08 22:01
411 查看
Capturing a country
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 380 Accepted Submission(s): 164
[align=left]Problem Description[/align]
Ant and Bob two army want to capture a country. The country is consist of N cities. To capture the city i, it takes Ant A[i] minutes, and Bob needs B[i]
minutes to capture city i. Due to the similarity of neighboring cities,
If the city i and j are neighboring cities, if Ant has captured city i,
then the time for Ant to capture city j is A[j]/2. Of course if Ant has captured city j, then the time for Ant to capture city i is A[i]/2.
It is the same for Bob. We define the total time to capture a country
be the time to capture city 1 + the time to capture city 2 + ... + the
time to capture city N. Now we want to know the minimal total time.
For simplicity, we assume that there is only one path to go from one city to another city.
[align=left]Input[/align]
The first line contains a integer N(0<N<100), which is the number of cities.Then following N lines describe A[1], A[2], …, A
;Then following N lines describe B[1], B[2], …, B
;Next comes N-1 lines, each contains two integers x, y, meaning that city x and city y are neighboring.
[align=left]Output[/align]
Just output the minimal total time in a single line.
[align=left]Sample Input[/align]
3
1 2 5
3 8 1
1 2
1 3
[align=left]Sample Output[/align]
3
[align=left]Source[/align]
2012 Multi-University Training Contest 5
[align=left]Recommend[/align]
zhuyuanchen520
终于把这道题的题解看明白了,,自己推了好长时间,又看了好长时间,汗。。。。。。。
题意: 两个人进攻n个城市,这n个城市构成一棵树,可以任意选择一个点开始,攻击已被自己攻击过的点的相邻点,
时间可以减半,两个人的攻击时间不一,两个人可以同时进行攻击。
看得是官方解题报告;
状态:dp[i][j][k] (0 <= i <= n, 0<=j<=1, 0 <= k <= 1) 表示以 i 为根的子树的费用,其中i节点被染成了第j种颜色,且子树中与i染成同一种颜色的与i连通的点集有k个点选取了完整的费用
那么 我们就可以得到 状态转移方程;
1:dp[ i ][ j ][ 0 ] = (所有以 i 为跟的 子树最小花费 的和 ) s + a[j][i]/2;
2:s = 求和 min(dp[ v ][j][0], dp[v][ 1 - j][1]) v 为 i 的子节点 ;理解:因为 在 1 中 k 值为 0 所以 与 i 连通的点 都没有取到 完整的值 及 其 子树的 k 值也为 0 ;因为 在 1 中 根节点 的颜色是 j (其子节点 必和其连通),所以,其子树中若要 然 其他的颜色 必有 第一个染 其他颜色的 节点 所以 1 - j 的 k 值 为 1;
3: dp[i][j][1] = min(cost[i][j] + S, cost[i][j]/2 + S + det);
det = min{dp[v][j][1] - min(dp[v][j][0], dp[v][1-j][1])};
若 和根节点 连通的(包括根节点本身)含有 第一个 染色 为 j 的节点 ,那么这个节点 要么是 根节点 本身 ,要么 在根节点的子树中,
若为 根节点 则 dp[ i][j ][1] = cost[i][j] + s (所有以 i 为跟的 子树最小花费 的和 ) ;
若在根节点的子树中 ,那么这个 节点 要求得必 是 子树中 花费最小的 det 就表示 这个节点的费用的 1/2 假设这个点在 以节点 v 为跟的子树中 (v是 i 的子节点)
det = dp[v][j][1] - 这棵子树的最小值 ;这棵子树的最小值为 min(dp[v][j][0], dp[v][1-j][1]) 然后 我们 枚举所有的子树 找到 最小的det 就可以了
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #include<string> #define Min(a,b) a<b?a:b #define Max(a,b) a>b?a:b #define CL(a,num) memset(a,num,sizeof(a)); #define maxn 205 #define inf 9999999 #define mx 1<<60 using namespace std; vector<int>g[maxn]; int dp[maxn][2][2],a[2][maxn],vis[maxn]; void dfs(int k) { int i,j; int len = g[k].size(); if( len == 0)// 为叶子节点 { dp[k][0][0] = a[0][k]/2; dp[k][0][1] = a[0][k]; dp[k][1][0] = a[1][k]/2; dp[k][1][1] = a[1][k]; return ; } for( i = 0; i < len ;++i) dfs(g[k][i]) ; for( i = 0;i < 2; ++i) { int sum = 0,det = inf ,tmp; for( j = 0; j < len ;++j) { int w = g[k][j]; tmp = min(dp[w][i][0],dp[w][1 - i][1]); sum +=tmp; det = min(det,dp[w][i][1] - tmp); } dp[k][i][0] = sum + a[i][k]/2; dp[k][i][1] = min(a[i][k] + sum ,a[i][k]/2 + sum + det); } } int main() { //freopen("data.in","r",stdin); int n, i, j,x,y,root; while(scanf("%d",&n)!=EOF) { for(j = 0; j < 2 ;++j) { for( i = 1; i <= n ;++i ) scanf("%d",&a[j][i]); } CL(vis,0); for(i = 0;i <= n;i++)g[i].clear(); for(i = 0; i < n - 1 ;++i) { scanf("%d%d",&x,&y); if( i ==0) root = x;//建的图是有向图,对解决问题没有影响,树形dp 就是 这样 if(!vis[y]) { g[x].push_back(y); vis[x] = 1; } else g[y].push_back(x); } CL(dp,0); dfs(root); int t1 = dp[root][0][1]; int t2 = dp[root][1][1]; printf("%d\n",min(t1,t2)); } }
相关文章推荐
- hdu 4340 Capturing a country(树形DP) 2012 Multi-University Training Contest 5
- 2017 Multi-University Training Contest 10 && HDU 6178 Monkeys 【贪心||树形DP】
- 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】
- hdu 4317 Unfair Nim (状态压缩DP) 【2012 Multi-University Training Contest 2】
- hdu 4317 Unfair Nim(状态压缩DP)——2012 Multi-University Training Contest 2
- 2012 Multi-University Training Contest 6-1010 hdu4359 Easy Tree DP?
- hdu 4385 Moving Bricks (状态压缩dp 2012 Multi-University Training Contest 9 )
- hdu 5291 Candy Distribution 2015 Multi-University Training Contest 1 树形dp,
- 2016 Multi-University Training Contest 2 1006 Fantasia (hdu5739) 【割点 无向图dfs树 树形dp】
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
- HDU-6178 Monkeys - 2017 Multi-University Training Contest - Team 10(树形DP)
- hdu 4374 One hundred layer (dp +单调队列 2012 Multi-University Training Contest 8 )
- 2012 Multi-University Training Contest 1
- 2012 Multi-University Training Contest 2
- 2012 Multi-University Training Contest 3
- 2012 Multi-University Training Contest 6
- 2012 Multi-University Training Contest 3:Triangle LOVE_判断有向图中是否含有仅由三个点组成的环
- hdu4366-successor-2012 Multi-University Training Contest 7-1007
- 2012 Multi-University Training Contest 7-1006 hdu4365 Palindrome graph
- 2015 Multi-University Training Contest 9(区间dp)