POJ 2152 Fire

Fire

Time Limit: 2000ms

Memory Limit: 65536KB

This problem will be judged on PKU. Original ID: 2152
64-bit integer IO format: %lld      Java class name: Main

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

解题:楼教主的题目真的很难

参考这位大牛的博客

$dp[i][j]表示结点i靠j消防,best[i]表示以i为根的子树的每个节点以u内的某个节点作为负责站的最小花费$

$$best[u] = min(dp[u][i])\  i \in subtree(u)$$

$if\ dis(u,i) > d_u \ ,u 不能靠i来消防$

$if \ dis(u,i) \leq d_u,这时候u可以靠i来消防,u的儿子也可以靠i来消防,儿子也可以靠自己内部的点来消防$

$初始化条件\ dp[u][i]  = dis(u,i) \leq limit[u]?cost[u]:+\infty$

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int maxn = 1010;
 6 const int INF = 0x3f3f3f3f;
 7 struct arc{
 8     int to,w,next;
 9     arc(int x = 0,int y = 0,int z = -1){
10         to = x;
11         w = y;
12         next = z;
13     }
14 }e[maxn*2];
15 int head[maxn],w[maxn],d[maxn],best[maxn],dis[maxn][maxn],tot,n;
16 int dp[maxn][maxn],m;
17 void add(int u,int v,int w){
18     e[tot] = arc(v,w,head[u]);
19     head[u] = tot++;
20 }
21 void dfs(int u,int fa,int dd,int root){
22     dis[root][u] = dd;
23     for(int i = head[u]; ~i; i = e[i].next){
24         if(e[i].to == fa) continue;
25         dfs(e[i].to,u,dd + e[i].w,root);
26     }
27 }
28 void solve(int u,int fa){
29     for(int i = 1; i <= n; ++i)
30         if(dis[u][i] <= d[u]) dp[u][i] = w[i];
31     for(int i = head[u]; ~i; i = e[i].next){
32         if(e[i].to == fa) continue;
33         solve(e[i].to,u);
34         for(int j = 1; j <= n; ++j)
35             if(dis[u][j] <= d[u])
36                 dp[u][j] += min(dp[e[i].to][j] - w[j],best[e[i].to]);
37     }
38     for(int i = 1; i <= n; ++i) best[u] = min(best[u],dp[u][i]);
39 }
40 int main(){
41     int kase,u,v,ww;
42     scanf("%d",&kase);
43     while(kase--){
44         memset(head,-1,sizeof head);
45         scanf("%d",&n);
46         for(int i = 1; i <= n; ++i)
47             scanf("%d",w + i);
48         for(int i = 1; i <= n; ++i)
49             scanf("%d",d + i);
50         tot = 0;
51         for(int i = 1; i < n; ++i){
52             scanf("%d%d%d",&u,&v,&ww);
53             add(u,v,ww);
54             add(v,u,ww);
55         }
56         memset(dp,0x3f,sizeof dp);
57         memset(best,0x3f,sizeof best);
58         for(int i = 1; i <= n; ++i) dfs(i,-1,0,i);
59         solve(1,-1);
60         printf("%d\n",best[1]);
61     }
62     return 0;
63 }

时间: 2024-08-10 19:18:52

POJ 2152 Fire的相关文章

POJ 2152 Fire(树形DP)

题意: 思路:令F[i][j]表示 的最小费用.Best[i]表示以i为根节点的子树多有节点都找到负责消防站的最小费用. 好难的题... 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 int tot,go[200005],first[200005],next[200005],val[2000

POJ 2152 Fire (树形DP,经典)

题意:给定一棵n个节点的树,要在某些点上建设消防站,使得所有点都能够通过某个消防站解决消防问题,但是每个点的建站费用不同,能够保证该点安全的消防站的距离上限也不同.给定每个点的建站费用以及最远的消防站距离上限,求保证该树安全的最小花费. 思路: 要选择部分点来建站解决消防问题,而总花费是有最优解的. 如何进行树形DP? 假设某点t的所有子树的消防问题都解决,而且已经获得最优解了,那么现在考虑的是点t的最优解问题,点t可以依靠任何点只要不超过距离限制即可,那枚举一下所有点试试,一旦t依靠某个点j解

POJ - 2152 Fire 树型DP

题目大意:有N座城市,要求在这N座城市中建一个消防系统,使得每座城市城市着火时都能被按时扑灭 现在给出每座城市建一个消防站所需的花费w和每座城市相邻消防站的最远距离lim(和该城市距离超过lim的城市的消防站无法救该城市的火),问要使所有的城市都能被救到火,建消防站的最小花费是多少 解题思路:参考了别人的题解,果然还是太弱了... 要使该城市能被救到火,那么消防站不是建在该点,就是建在以该点为根的子树上,或者是该点的父节点上,他肯定要依赖其中一个城市的消防站的 设dp[i][j]表示以i城市为根

Fire (poj 2152 树形dp)

Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同时花费为v[i].问最小花费. 以前做过一道类似的题(水库),这道题也差不多.首先来考虑,用\(best[i]\)表示以i为根的子树的最小花费.这样做有什么问题呢?它无法很好的处理消防站重复建的问题. 所以换一种做法.\(best[i]\)依然表示原来的含义,新建一个数组\(f[i][j]\),表示当i这个结

poj 2607 Fire Station (spfa)

Fire Station Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3783   Accepted: 1337 Description A city is served by a number of fire stations. Some residents have complained that the distance from their houses to the nearest station is to

POJ 2607 Fire Station

枚举+最短路问题. 题意依然晦涩难懂. 新建一个消防站n 可以使得所有交叉路口到最近的一个消防站的距离中最大值减小,且n 是满足条件的交叉路口序号中序号最小的. 先每个消防站做SPFA.找到所有点 到最近消防站的 距离. 然后枚举 每个不是消防站的点,找到距离这个点的最大距离.然后比对 最大是否更新了. ORZ的是,输入边的时候要EOF.简直-- 谁是出题人,看我不把他脸按到键OWIHW#ROIJHA(P*#RY(#*Y(*#@UISHIUOHEOIF #include<cstdio> #in

树形 DP 总结

本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在"树"的数据结构上的动态规划,平时作的动态规划都是线性的或者是建立在图上的,线性的动态规划有二种方向既向前和向后,相应的线性的动态规划有二种方法既顺推与逆推,而树型动态规划是建立在树上的,所以也相应的有二个方向: 1.叶->根:在回溯的时候从叶子节点往上更新信息 2.根 - >叶:往往是在从叶往根d

【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock&#39;s blog】

树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AVL树,线段树.SPLAY树,后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点.这里面的关键就是返回的信息部分,这个也没一般性的东西可讲

poj 动态规划题目列表及总结

此文转载别人,希望自己能够做完这些题目! 1.POJ动态规划题目列表 容易:1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1208, 1276,1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740(博弈),1742, 1887, 1926(马尔科夫矩阵,求平衡), 1936, 1952, 1953, 1958, 1959, 1962, 1975,