【POJ 2152】 Fire
【题目链接】
【算法】
同样是树形DP,但是比较难,笔者做这题看了题解
令f[i][j]表示在以i为根的子树中
1.在以i为根的子树中建一些消防站
2.在节点j必须建一个消防站
3.以i为根的子树中,每个节点在满足距离不超过D的前提下,选一个子树内的节点或节点j作为“负责站”
4.节点i的负责站必须是节点j
的最小代价
考虑转移,为了转移方便,我们用一个辅助状态best[i]表示以i为根的子树中,每个节点在满足距离不超过D的前提下,
选一个子树内的节点作为“负责站”的最小代价,显然 : best[i] = min{f[i][j]}(j在以i为根的子树中)
当dis(i,j) > Di时,f[i][j] = +oo(正无穷,表示不存在这种状态
当dis(i,j) <= Di时,它的每个子节点k有两种选择 :
1.选择子树内的节点为“负责站”,代价为best[k]
2.选择j为它的“负责站”,代价为f[k][j]
因此f[i][j] = w[j] + sigma(min{best[k],f[k][j]}) (k为i的孩子)
最后,best[1]就是答案
【代码】
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 1010
const int INF = 2e9; int i,T,n,u,v,l;
vector< pair<int,int> > e[MAXN];
int dis[MAXN],best[MAXN],w[MAXN],d[MAXN],f[MAXN][MAXN]; inline void getdist(int x)
{
int i,y;
for (i = ; i < e[x].size(); i++)
{
y = e[x][i].first;
if (dis[y] == -)
{
dis[y] = dis[x] + e[x][i].second;
getdist(y);
}
}
}
inline void dfs(int x,int fa)
{
int i,j,y;
for (i = ; i < e[x].size(); i++)
{
y = e[x][i].first;
if (fa != y) dfs(y,x);
}
for (i = ; i <= n; i++) dis[i] = -;
dis[x] = ;
getdist(x);
best[x] = INF;
for (i = ; i <= n; i++) f[x][i] = INF;
for (i = ; i <= n; i++)
{
if (dis[i] <= d[x])
{
f[x][i] = w[i];
for (j = ; j < e[x].size(); j++)
{
y = e[x][j].first;
if (fa != y) f[x][i] += min(best[y],f[y][i]-w[i]);
}
best[x] = min(best[x],f[x][i]);
}
}
} int main()
{ scanf("%d",&T); while (T--)
{
scanf("%d",&n);
for (i = ; i <= n; i++) e[i].clear();
for (i = ; i <= n; i++) scanf("%d",&w[i]);
for (i = ; i <= n; i++) scanf("%d",&d[i]);
for (i = ; i < n; i++)
{
scanf("%d%d%d",&u,&v,&l);
e[u].push_back(make_pair(v,l));
e[v].push_back(make_pair(u,l));
}
dfs(,);
printf("%d\n",best[]);
} return ; }
【POJ 2152】 Fire的更多相关文章
- 【POJ 2152】 Fire (树形DP)
Fire Description Country Z has N cities, which are numbered from 1 to N. Cities are connected by h ...
- bzoj 2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- BZOJ2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 284 Solved: 82[Submit][St ...
- BZOJ2293: 【POJ Challenge】吉他英雄
2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 80 Solved: 59[Submit][Stat ...
- BZOJ2287: 【POJ Challenge】消失之物
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 254 Solved: 140[Submit][S ...
- BZOJ2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 126 Solved: 90[Submit][Sta ...
- BZOJ2296: 【POJ Challenge】随机种子
2296: [POJ Challenge]随机种子 Time Limit: 1 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 114 Solv ...
- BZOJ2292: 【POJ Challenge 】永远挑战
2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 513 Solved: 201[Submit][ ...
随机推荐
- POJ3528移石头
题目大意: 河道两旁直线上有两块石头不能移动,距离为L,但中间放置了N块石头并列出这N块石头到起点的距离,可以移走M块,那么移走石头后每次牛跨石头的最小距离如何达到最大值,输出这个最大值 让最小距离的 ...
- bzoj 2818 GCD 数论 欧拉函数
bzoj[2818]Gcd Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Samp ...
- 【BZOJ3939】Cow Hopscotch(动态开点线段树)
题意: 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几乎总是不愉快地结束,但是这并没有阻止奶牛们在每天下午参加跳格子游戏 游戏在一个R* ...
- BZOJ3126: [Usaco2013 Open]Photo
n<=200000个点,m<=100000个区间,每个区间有且仅有一个点,求最多几个点,无解-1. http://www.cnblogs.com/Chorolop/p/7570191.ht ...
- 如何使用google解决问题
如何使用google解决问题 redguardtoo著 文章选自2004年<程序员>杂志第8期P56 前面收集了篇如何问问题的文章就是<学会提问>http://blog.pro ...
- java基础编程题
1. 某公司每月标准上班时间是160小时,每小时工资是30元. 如果上班时间超出了160小时,超出部分每小时按1.5倍工资发放.请编写程序计算员工月工资. package com.num2.lianx ...
- 使用微软的 ilasm 和 ildasm 对. net程序进行编译和反编译
为了保证示例的完整性,请先准备好一个 c#写的 exe 程序,或者可以使用我提供的 exe 程序也可以(很简单,为了测试这里仅生成了一个带按钮的 winform,单击按钮提示弹窗) Test WinF ...
- firedac数据集的序列和还原
procedure TForm1.Button1Click(Sender: TObject);var stream, stream2: TMemoryStream; buf: TBytes;begin ...
- FM算法及FFM算法
转自:http://tech.meituan.com/deep-understanding-of-ffm-principles-and-practices.html http://blog.csdn. ...
- Nginx在Linux下的安装部署
Nginx简单介绍 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 server,也是一个 IMAP/POP3/SMTP server.Nginx作为 ...