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[200005];
 7 int dis[200005],f[2005][2005];
 8 int n,w[200005],d[200005],best[200005];
 9 void insert(int x,int y,int z){
10     tot++;
11     go[tot]=y;
12     next[tot]=first[x];
13     first[x]=tot;
14     val[tot]=z;
15 }
16 void add(int x,int y,int z){
17     insert(x,y,z);
18     insert(y,x,z);
19 }
20 void Dfs(int x){
21     for (int i=first[x];i;i=next[i]){
22         int pur=go[i];
23         if (dis[pur]!=-1) continue;
24         dis[pur]=dis[x]+val[i];
25         Dfs(pur);
26     }
27 }
28 void dfs(int x,int fa){
29     for (int i=first[x];i;i=next[i]){
30         int pur=go[i];
31         if (pur==fa) continue;
32         dfs(pur,x);
33     }
34     for (int i=1;i<=n;i++) dis[i]=-1;
35     dis[x]=0;
36     Dfs(x);best[x]=99999999;
37     for (int i=1;i<=n;i++) f[x][i]=99999999;
38     for (int i=1;i<=n;i++)
39      if (dis[i]<=d[x]){
40             f[x][i]=w[i];
41             for (int j=first[x];j;j=next[j]){
42                 int pur=go[j];
43                 if (pur==fa) continue;
44                 f[x][i]+=std::min(best[pur],f[pur][i]-w[i]);
45             }
46             best[x]=std::min(best[x],f[x][i]);
47     }
48 }
49 int main(){
50     int T;
51     scanf("%d",&T);
52     while (T--){
53         scanf("%d",&n);
54         for (int i=1;i<=n;i++) scanf("%d",&w[i]);
55         for (int i=1;i<=n;i++) scanf("%d",&d[i]);
56         tot=0;
57         for (int i=1;i<=n;i++) first[i]=0;
58         for (int i=1;i<n;i++){
59             int x,y,z;
60             scanf("%d%d%d",&x,&y,&z);
61             add(x,y,z);
62         }
63         dfs(1,0);
64         printf("%d\n",best[1]);
65     }
66 }
时间: 2024-10-05 09:10:18

POJ 2152 Fire(树形DP)的相关文章

poj2152(Fire) 树形DP

题目链接:http://poj.org/problem?id=2152 题意:一棵带边权的树,边权表示节点间距离,在i上建立消防站的代价是w[i],如果在一点i没建消防站,那么它与距离这个点最近的消防站之间的距离不能大于d[i].问满足建站最小的花费: 解法:看了陈启峰的论文才会的,感觉挺难的,不过论文里分情况讨论了,应该不需要:dp[i][j]表示在i处选择j处作为供应站(但是并不一定要求是最近的,这样即使有更近的也无所谓,和论文里有出入.),best[i]表示i及其子树满足要求的最小花费,那

POJ 2342 (树形DP)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3863   Accepted: 2172 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

POJ 2152 Fire (树形DP,经典)

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

POJ 1849 Two (树形dp 树的直径 两种方法)

Two Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1232   Accepted: 619 Description The city consists of intersections and streets that connect them. Heavy snow covered the city so the mayor Milan gave to the winter-service a list of st

[POJ 1155] TELE (树形dp)

题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每两个节点之间传播的成本,给你每个观众会付的钱,问你电视台在不亏本的情况下最多能给多少个观众看节目. 这是我的第一道树形dp..无耻的看了题解.. 设计状态:dp[u][i]代表以u为根的子树中有i个观众,能够得到的最大收入. 状态转移:dp[u][i] = max(dp[u][i],dp[u][i-

poj 1947 经典树形dp

经典树形dp:问在一棵树上最少删除多少条边可以分离出一个节点数为p的子树. 定义状态: dp[i][j]表示从i为根的子树上分离出一个节点数为j的子树的代价(最少需要删除的边数). 考虑i节点的每个儿子ii,ii可以选或者不选(切断),然后就转化成了背包问题. dp[u][j] = min( dp[u][j], dp[u][j - k] + dp[v][k] ); 1 #include <iostream> 2 #include <cstring> 3 #include <c

POJ Anniversary party 树形DP

/* 树形dp: 给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大 对于每一个节点,我们有两种状态 dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能获得的最大权值和 dp[i][1]表示选择节点i ,同上! 转移方程: dp[i][0]+=max(dp[i_son][1],dp[i_son][0])如果没选择的话,那么子树可选择可不选择 dp[i][1]+=dp[i_son][0] 选择了之后,子树只能不选择 最后输出max(dp[i][0],

POJ 2486-Apple Tree(树形DP)(难)

题意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 思路:(思路转自http://blog.csdn.net/libin56842/article/details/10101807) 树形dp,比较经典的一个树形dp.首先很容易就可以想到用dp[root][k]表示以root为根的子树中最多走k时所能获得的最多苹果数,接下去我们很习惯地会想到将k步在root的所有子结点中分配,也就是进行一次背包,就可以得出此时状态的最优解了,但是这里还有一个问

POJ - 2152 Fire 树型DP

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