【POJ2152】Fire——树形DP
来源:互联网 发布:传奇怪物补丁算法 编辑:程序博客网 时间:2024/05/20 09:46
Fire
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 1294 Accepted: 669
Description
Country Z has N cities, which are numbered from 1 to N. Cities are connected by highways, and there is exact one path between two different cities. Recently country Z often caught fire, so the government decided to build some firehouses in some cities. Build a firehouse in city K cost W(K). W for different cities may be different. If there is not firehouse in city K, the distance between it and the nearest city which has a firehouse, can’t be more than D(K). D for different cities also may be different. To save money, the government wants you to calculate the minimum cost to build firehouses.
Input
The first line of input contains a single integer T representing the number of test cases. The following T blocks each represents a test case.
The first line of each block contains an integer N (1 < N <= 1000). The second line contains N numbers separated by one or more blanks. The I-th number means W(I) (0 < W(I) <= 10000). The third line contains N numbers separated by one or more blanks. The I-th number means D(I) (0 <= D(I) <= 10000). The following N-1 lines each contains three integers u, v, L (1 <= u, v <= N,0 < L <= 1000), which means there is a highway between city u and v of length L.
Output
For each test case output the minimum cost on a single line.
Sample Input
5
5
1 1 1 1 1
1 1 1 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5
1 1 1 1 1
2 1 1 1 2
1 2 1
2 3 1
3 4 1
4 5 1
5
1 1 3 1 1
2 1 1 1 2
1 2 1
2 3 1
3 4 1
4 5 1
4
2 1 1 1
3 4 3 2
1 2 3
1 3 3
1 4 2
4
4 1 1 1
3 4 3 2
1 2 3
1 3 3
1 4 2
Sample Output
2
1
2
2
3
Source
POJ Monthly,Lou Tiancheng
Translation
给一棵带权树,每个节点需要被覆盖,覆盖节点i的方法为一下二者之一:
- 用
wi 的价格在该点建消防站 - 在该点距离
di 的范围内有至少一个消防站
求覆盖整棵树的最小代价
Solution
记dp[i][j]表示第i号节点被j号节点覆盖,且i号节点的子树被全部覆盖的最小代价,best[i]表示将i号节点的子树全部覆盖的最小代价,dis[i][j]表示树上两点i,j间的距离
dis[i][j]可以用
dp[i][j]和best[i]可以这样转移
其中,由于每一个dp[k][j]都包含了w[j],所以我们在统计儿子时要将其去掉,并在最后加上
最后的答案便是best[root],root可以任定
Code
/*POJ2152Author:Johann*/#include <iostream>#include <cstdio>#include <cstdlib>#include <queue>#include <algorithm>#include <cmath>#include <iomanip>#include <cstring>using namespace std;#define rep(i, a, b) for(int i = (a); i <= (b); i++)#define red(i, a, b) for(int i = (a); i >= (b); i--)#define ll long longinline int read() { char c = getchar(); int x = 0; while(!isdigit(c)) c = getchar(); while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x;}const int N = 1500;const int inf = 1000000000;struct edge{ int from, to, len, nxt;}e[N * 2];int dp[N][N], dis[N][N];int head[N], best[N], vis[N], w[N], d[N], lst[N];int q[N];int T, n, tail = 0, cnt = 0;void addedge(int x, int y, int z) { e[++tail].from = x; e[tail].to = y; e[tail].len = z; e[tail].nxt = head[x]; head[x] = tail;}void work(int root) { if (root == 1) lst[cnt = 1] = 1; memset(vis, 0, sizeof(vis)); dis[root][root] = 0; vis[root] = 1; int l = 1, r = 1; q[1] = root; while(l <= r) { int x = q[l]; l++; for(int i = head[x]; i != -1; i = e[i].nxt) { int v = e[i].to; if (!vis[v]) { vis[v] = 1; if (root == 1) lst[++cnt] = v; dis[root][v] = dis[root][x] + e[i].len; q[++r] = v; } } }}void DP() { memset(vis, 0, sizeof(vis)); red(k, n, 1) { int u = lst[k]; vis[u] = 1; best[u] = inf; rep(j, 1, n) { if (dis[u][j] > d[u]) { dp[u][j] = inf; continue; } dp[u][j] = 0; for(int i = head[u]; i != -1; i = e[i].nxt) { int v = e[i].to; if (!vis[v]) continue; dp[u][j] += min(dp[v][j] - w[j], best[v]); } dp[u][j] += w[j]; if (dp[u][j] < best[u]) best[u] = dp[u][j]; } }}int main() { scanf("%d", &T); while(T--) { tail = 0; n = read(); rep(i, 1, n) w[i] = read(); rep(i, 1, n) d[i] = read(); rep(i, 1, n) head[i] = -1; rep(i, 1, n - 1) { int x = read(), y = read(), z = read(); addedge(x, y, z); addedge(y, x, z); } rep(i, 1, n) work(i); DP(); printf("%d\n", best[1]); } return 0;}
尾声
终于拿到新键盘了,写题的动力!
茶轴真棒!
千万不能把Codeforces的习惯带入POJ(可见BZOJ的优越),第一次体会到STL Queue被卡T的快感
陈启峰论文题……好吧的确不容易
老大在机房里开了监!控!
监!控!
重复一遍,HBH是心机婊
End.
- 【POJ2152】Fire——树形DP
- POJ2152 Fire 树形DP
- poj2152(Fire) 树形DP
- 【poj2152】【Fire】【树形dp】
- 【poj2152】Fire 树形DP
- POJ2152 树形DP
- POJ2152 Fire
- 树形dp(Fire)
- 【POJ 2152】Fire【树形DP】
- Fire - POJ 2152 树形dp
- poj 2152 Fire 树形dp
- poj 2152 Fire 树形DP
- 【树形DP】 POJ 2152 Fire
- [树形DP] POJ 2152 Fire
- Poj 2152 Fire (DP_树形DP)
- ***POJ 2152 - Fire(树形DP)
- poj 2152 Fire - 经典树形dp
- POJ 2152 Fire (树形DP,有趣)
- NSTimer
- C++ 文件读写
- 自定义异常类
- PHP7新特性
- Android 自定义View
- 【POJ2152】Fire——树形DP
- 顺序表的应用实例
- extjs panel layoutconfig属性
- POJ 3280 Cheapest Palindrome(区间DP)
- 定位UNIX上常见问题的经验总结
- Swift学习day2之Tuple
- [Android高级知识][1] 如何调用支付宝接口
- MySQL Cluster 7.4.8集群安装及遇到的问题
- POJ 3267:The Cow Lexicon 字符串匹配dp