fire poj-2152

    题目大意:给出一颗树,给出两个相邻节点的距离,以及每个节点的接受范围,还有当前节点的代价。我们想要求出覆盖整个图的最小代价。

    注释:一个点被覆盖,当且仅当该点有防火站或者这个点的接受范围之内有防火站。计算两个不相邻节点的距离用LCA计算。节点数<=1000,接受范围<=10,000.

      想法:poj最后一道树形dp,用这道神一样的树形dp结尾,在好不过。

      对于一个节点来讲设几个状态:ans[pos]表示使以pos为根的子树被保护的最小代价。dp[pos][save]表示以pos为根的子树被保护的最小代价且pos节点必须被save节点保护。dist[i][j]表示i到j的距离。cost[i]表示在该节点建立防火站的代价。d[i]表示该节点的接受范围。

      然后,我们考虑神奇的转移:$dp[u][v]=cost[v]+\sum min(dp[k][v]-cost[v],ans[k])$。这个状态的充要条件是k也可以被v覆盖。如果不然,我们就直接将dp[u][v]+=ans[k]。

    最后,附上丑陋的代码... ...

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <queue>
  6. #define N 2100
  7. using namespace std;
  8. const int inf=1e9;
  9. int cost[N],d[N],n;
  10. int dist[N][N];
  11. int val[N];
  12. int dp[N][N];
  13. int head[N];
  14. int ans[N];
  15. int to[N];
  16. int nxt[N];
  17. int tot;
  18. queue<int>q;
  19. inline void add(int x,int y,int z)
  20. {
  21. to[++tot]=y;
  22. val[tot]=z;
  23. nxt[tot]=head[x];
  24. head[x]=tot;
  25. }
  26. void get_dist(int dist[],int s)
  27. {
  28. dist[s]=0;
  29. q.push(s);
  30. while(q.size())
  31. {
  32. int u=q.front(); q.pop();
  33. for(int i=head[u];i;i=nxt[i])
  34. {
  35. int v=to[i];
  36. if(!dist[v]&&v!=s)
  37. {
  38. dist[v]=dist[u]+val[i];
  39. q.push(v);
  40. }
  41. }
  42. }
  43. }
  44. void dfs(int pos,int fa)
  45. {
  46. for(int i=head[pos];i;i=nxt[i])
  47. {
  48. if(to[i]==fa) continue;
  49. dfs(to[i],pos);
  50. }
  51. for(int v=1;v<=n;v++)
  52. {
  53. if(dist[pos][v]<=d[pos])
  54. {
  55. int temp=0;
  56. for(int i=head[pos];i;i=nxt[i])
  57. {
  58. int k=to[i];
  59. if(k==fa) continue;
  60. temp+=min(dp[k][v]-cost[v],ans[k]);
  61. }
  62. dp[pos][v]=cost[v]+temp;
  63. }
  64. else dp[pos][v]=inf;
  65. }
  66. for(int i=1;i<=n;i++)
  67. {
  68. ans[pos]=min(ans[pos],dp[pos][i]);
  69. }
  70. }
  71. inline void original()
  72. {
  73. tot=0;
  74. memset(head,0,sizeof head);
  75. memset(dp,0,sizeof dp);
  76. memset(dist,0,sizeof dist);
  77. memset(ans,63,sizeof ans);
  78. }
  79. int main()
  80. {
  81. int cases;
  82. scanf("%d",&cases);
  83. while(cases--)
  84. {
  85. original();
  86. scanf("%d",&n);
  87. for(int i=1;i<=n;i++)
  88. {
  89. scanf("%d",&cost[i]);
  90. }
  91. for(int i=1;i<=n;i++)
  92. {
  93. scanf("%d",&d[i]);
  94. }
  95. int a,b,c;
  96. for(int i=1;i<n;i++)
  97. {
  98. scanf("%d%d%d",&a,&b,&c);
  99. add(a,b,c);
  100. add(b,a,c);
  101. }
  102. for(int i=1;i<=n;i++)
  103. {
  104. get_dist(dist[i],i);
  105. }
  106. dfs(1,0);
  107. printf("%d\n",ans[1]);
  108. }
  109. return 0;
  110. }

    小结:太tm神了。其中,计算节点距离的处理是很巧妙地... ...

[poj2152]fire_树形dp的更多相关文章

  1. POJ2152 Fire (树形DP)

    题意:n个城市n-1条边 组成一棵树 在每个城市修建消防站会有一个花费costi 每个城市能防火当且仅当地图上距离他最近的消防站距离小于di   问如何修建消防站 使地图上所有的城市都有预防火灾的能力 ...

  2. poj2152 Fire(树形DP)

    题目链接:https://vjudge.net/problem/POJ-2152 题意:给定一颗大小为n的树,在每个结点建消防站花费为w[i],如果某结点没有消防站,只要在它距离<=d[i]的结 ...

  3. 树形DP小结

    树形DP1.简介:树是一种数据结构,因为树具有良好的子结构,而恰好DP是从最优子问题更新而来,那么在树上做DP操作就是从树的根节点开始深搜(也就是记忆化搜索),保存每一步的最优结果.tips:树的遍历 ...

  4. 树形 DP 总结

    树形 DP 总结 本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在“树 ...

  5. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  6. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  7. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  8. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  9. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

随机推荐

  1. HI3531编译helloworld,执行错误

    若在嵌入式系统中执行某文件出现如下错误: -/bin/sh: XXX: not found 一般是因为缺少库文件,解决方法有2: 1,文件系统的busybox编译时使用动态编译方式 2,或编译该文件的 ...

  2. (三十一)java多线程二

    因为线程在执行的过程中具有一定的不确定性,在并发的时候就会出现安全问题,因此一般需要采取一定的措施来保证线程的安全,同步代码块就是其中一种方式. 以下是模拟银行取钱的多线程小例子,两个都能确保安全,但 ...

  3. directX根据设备类GUID查询所属的filter

    hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0);    ASSERT(SUCCEEDED(hr));    ...

  4. 芝麻HTTP:Flask的安装

    Flask是一个轻量级的Web服务程序,它简单.易用.灵活,这里主要用来做一些API服务. 1. 相关链接 GitHub:https://github.com/pallets/flask 官方文档:h ...

  5. 芝麻HTTP:TXT文本存储

    将数据保存到TXT文本的操作非常简单,而且TXT文本几乎兼容任何平台,但是这有个缺点,那就是不利于检索.所以如果对检索和数据结构要求不高,追求方便第一的话,可以采用TXT文本存储.本节中,我们就来看下 ...

  6. 芝麻HTTP:Python爬虫实战之爬取糗事百科段子

    首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致之前的代码没法用了,会导致无法输出和CPU占用过高的 ...

  7. MongoDB的安装和配置(Windows系统)及遇到的常见问题解答

    目前比较流行的数据库大致可以分为三种: 前两种是按照图论理论建立起来的,分别是: 层次式数据库(IMS(Information Management System)是其典型代表)和 网络式数据库(DB ...

  8. pat1111-1120

    1111 比较麻烦的最短路 #include<cmath> #include<map> #include<iostream> #include<cstring ...

  9. pat1071-1080

    1071 #include<iostream> #include<cstdio> #include<cstring> #include<vector> ...

  10. 通过Navicat连接MySQL数据库

    步骤一.从Navicat官网下载Navicat11版本安装包安装 下载连接:http://www.formysql.com/xiazai_mysql.html 步骤二.下载补丁破解程序PatchNav ...