[poj2152]fire_树形dp
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]。
最后,附上丑陋的代码... ...
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cstring>
- #include <queue>
- #define N 2100
- using namespace std;
- const int inf=1e9;
- int cost[N],d[N],n;
- int dist[N][N];
- int val[N];
- int dp[N][N];
- int head[N];
- int ans[N];
- int to[N];
- int nxt[N];
- int tot;
- queue<int>q;
- inline void add(int x,int y,int z)
- {
- to[++tot]=y;
- val[tot]=z;
- nxt[tot]=head[x];
- head[x]=tot;
- }
- void get_dist(int dist[],int s)
- {
- dist[s]=0;
- q.push(s);
- while(q.size())
- {
- int u=q.front(); q.pop();
- for(int i=head[u];i;i=nxt[i])
- {
- int v=to[i];
- if(!dist[v]&&v!=s)
- {
- dist[v]=dist[u]+val[i];
- q.push(v);
- }
- }
- }
- }
- void dfs(int pos,int fa)
- {
- for(int i=head[pos];i;i=nxt[i])
- {
- if(to[i]==fa) continue;
- dfs(to[i],pos);
- }
- for(int v=1;v<=n;v++)
- {
- if(dist[pos][v]<=d[pos])
- {
- int temp=0;
- for(int i=head[pos];i;i=nxt[i])
- {
- int k=to[i];
- if(k==fa) continue;
- temp+=min(dp[k][v]-cost[v],ans[k]);
- }
- dp[pos][v]=cost[v]+temp;
- }
- else dp[pos][v]=inf;
- }
- for(int i=1;i<=n;i++)
- {
- ans[pos]=min(ans[pos],dp[pos][i]);
- }
- }
- inline void original()
- {
- tot=0;
- memset(head,0,sizeof head);
- memset(dp,0,sizeof dp);
- memset(dist,0,sizeof dist);
- memset(ans,63,sizeof ans);
- }
- int main()
- {
- int cases;
- scanf("%d",&cases);
- while(cases--)
- {
- original();
- scanf("%d",&n);
- for(int i=1;i<=n;i++)
- {
- scanf("%d",&cost[i]);
- }
- for(int i=1;i<=n;i++)
- {
- scanf("%d",&d[i]);
- }
- int a,b,c;
- for(int i=1;i<n;i++)
- {
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,c);
- add(b,a,c);
- }
- for(int i=1;i<=n;i++)
- {
- get_dist(dist[i],i);
- }
- dfs(1,0);
- printf("%d\n",ans[1]);
- }
- return 0;
- }
小结:太tm神了。其中,计算节点距离的处理是很巧妙地... ...
[poj2152]fire_树形dp的更多相关文章
- POJ2152 Fire (树形DP)
题意:n个城市n-1条边 组成一棵树 在每个城市修建消防站会有一个花费costi 每个城市能防火当且仅当地图上距离他最近的消防站距离小于di 问如何修建消防站 使地图上所有的城市都有预防火灾的能力 ...
- poj2152 Fire(树形DP)
题目链接:https://vjudge.net/problem/POJ-2152 题意:给定一颗大小为n的树,在每个结点建消防站花费为w[i],如果某结点没有消防站,只要在它距离<=d[i]的结 ...
- 树形DP小结
树形DP1.简介:树是一种数据结构,因为树具有良好的子结构,而恰好DP是从最优子问题更新而来,那么在树上做DP操作就是从树的根节点开始深搜(也就是记忆化搜索),保存每一步的最优结果.tips:树的遍历 ...
- 树形 DP 总结
树形 DP 总结 本文转自:http://blog.csdn.net/angon823/article/details/52334548 介绍 1.什么是树型动态规划 顾名思义,树型动态规划就是在“树 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
随机推荐
- HI3531编译helloworld,执行错误
若在嵌入式系统中执行某文件出现如下错误: -/bin/sh: XXX: not found 一般是因为缺少库文件,解决方法有2: 1,文件系统的busybox编译时使用动态编译方式 2,或编译该文件的 ...
- (三十一)java多线程二
因为线程在执行的过程中具有一定的不确定性,在并发的时候就会出现安全问题,因此一般需要采取一定的措施来保证线程的安全,同步代码块就是其中一种方式. 以下是模拟银行取钱的多线程小例子,两个都能确保安全,但 ...
- directX根据设备类GUID查询所属的filter
hr = m_pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0); ASSERT(SUCCEEDED(hr)); ...
- 芝麻HTTP:Flask的安装
Flask是一个轻量级的Web服务程序,它简单.易用.灵活,这里主要用来做一些API服务. 1. 相关链接 GitHub:https://github.com/pallets/flask 官方文档:h ...
- 芝麻HTTP:TXT文本存储
将数据保存到TXT文本的操作非常简单,而且TXT文本几乎兼容任何平台,但是这有个缺点,那就是不利于检索.所以如果对检索和数据结构要求不高,追求方便第一的话,可以采用TXT文本存储.本节中,我们就来看下 ...
- 芝麻HTTP:Python爬虫实战之爬取糗事百科段子
首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致之前的代码没法用了,会导致无法输出和CPU占用过高的 ...
- MongoDB的安装和配置(Windows系统)及遇到的常见问题解答
目前比较流行的数据库大致可以分为三种: 前两种是按照图论理论建立起来的,分别是: 层次式数据库(IMS(Information Management System)是其典型代表)和 网络式数据库(DB ...
- pat1111-1120
1111 比较麻烦的最短路 #include<cmath> #include<map> #include<iostream> #include<cstring ...
- pat1071-1080
1071 #include<iostream> #include<cstdio> #include<cstring> #include<vector> ...
- 通过Navicat连接MySQL数据库
步骤一.从Navicat官网下载Navicat11版本安装包安装 下载连接:http://www.formysql.com/xiazai_mysql.html 步骤二.下载补丁破解程序PatchNav ...