题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739

做这道题主要是为了加强自己对SPFA的代码的训练以及对树dp的一些思路的锻炼。我特地研究了一下树dp的部分

for (int i = t; i >= w; i--){
for (int j = i-w; j >= 0; j--){
dp[u][i] = max(dp[u][i], dp[u][j]+dp[v][i - j - w]);
}
}

循环里面是不能搞错顺序的,外层的i逆序显然,但为什么里层会有问题呢? 因为w是可以=0的,这个时候想像一下,如果j=i-w的话,那么就会有

dp[u][i]=max(dp[u][i],dp[u][i]+dp[v][i-j-w]),但是dp[u][i]是已经更新了的,所以这样会出错,两层循环都必须要逆序。

下面贴一记代码

#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define maxn 150
using namespace std; struct Edge
{
int u, v, w;
Edge(){}
Edge(int ui, int vi, int wi) :u(ui), v(vi), w(wi){}
}e[2*maxn]; int n, t;
int val[maxn];
int ecnt; int first[maxn], nxt[2 * maxn]; void add(int u, int v, int w)
{
e[ecnt].u = u; e[ecnt].v = v; e[ecnt].w = w;
nxt[ecnt] = first[u];
first[u] = ecnt++;
} int dis[maxn], vis[maxn];
int p[maxn]; void spfa(int s)
{
memset(dis, 0x3f, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(p, -1, sizeof(p));
queue<int> que;
que.push(s); vis[s] = 1;
dis[s] = 0;
while (!que.empty())
{
int u = que.front(); que.pop();
vis[s] = 0;
for (int i = first[u]; i != -1; i = nxt[i]){
int v = e[i].v;
if (dis[v] > dis[u] + e[i].w){
dis[v] = dis[u] + e[i].w;
p[v] = i;
if (!vis[v]){
que.push(v);
vis[v] = 1;
}
}
}
}
} int dp[maxn][550]; void dfs(int u, int fa)
{
for (int i = first[u]; i != -1; i = nxt[i]){
int v = e[i].v, w = e[i].w * 2;
if (v == fa) continue;
dfs(v, u);
for (int i = t; i >= w; i--){
for (int j = i-w; j >= 0; j--){
dp[u][i] = max(dp[u][i], dp[u][j]+dp[v][i - j - w]);
}
}
}
for (int i = 0; i <= t; i++){
dp[u][i] += val[u];
}
} int main()
{
while (cin >> n >> t)
{
int ui, vi, wi;
memset(first, -1, sizeof(first));
ecnt = 0;
for (int i = 0; i < n - 1; i++){
scanf("%d%d%d", &ui, &vi, &wi);
add(ui, vi, wi);
add(vi, ui, wi);
}
for (int i = 1; i <= n; i++) scanf("%d", val + i);
spfa(1);
if (dis[n]>t) {
puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
continue;
}
for (int i = n; i != 1; i = e[p[i]].u){
e[p[i]].w = e[p[i] ^ 1].w = 0;
}
t -= dis[n];
memset(dp, 0, sizeof(dp));
dfs(1, -1);
printf("%d\n", dp[1][t]);
}
return 0;
}

HDU4276 The Ghost Blows Light SPFA&&树dp的更多相关文章

  1. HDU4276 The Ghost Blows Light(树形DP+背包)

    题目大概说一棵n个结点树,每个结点都有宝藏,走过每条边要花一定的时间,现在要在t时间内从结点1出发走到结点n,问能获得最多的宝藏是多少. 放了几天的题,今天拿出来集中精力去想,还是想出来了. 首先,树 ...

  2. HDU-4276 The Ghost Blows Light (树形DP+背包)

    题目大意:在一个n个节点的树形迷宫中,1为起点,n为出口.每个节点上有一定价值的珠宝,在节点之间移动的时间已知,问在能走出迷宫的前提下并且不超过m的时间内能收集的最多珠宝是多少? 题目分析:在树上,从 ...

  3. 【HDU 4276】The Ghost Blows Light(树形DP,依赖背包)

    The Ghost Blows Light Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The t ...

  4. HDU4276 - The Ghost Blows Light(树形DP)

    题目大意 给定一棵n个结点的树,每个结点上有一定数量的treasure,经过每条边需要花一定的时间,要求你从结点1出发,在不超过时间T的情况下,最多能够获得的treasure是多少,并且要求结束于结点 ...

  5. HDU 4276-The Ghost Blows Light(树状背包)

    题意: n个房间,每个有一定的钱,一个房间到另一个房间花费一定的时间,给你房间连接树,求在t时间内到达房间m能得到的最大钱数(从房间1(根)出发) 分析: 该题关键是最后要到达m,没有这个条件,就是基 ...

  6. HDU 4276 The Ghost Blows Light (树形DP,变形)

    题意:给定一棵n个节点的树,起点是1,终点是n,每经过一条边需要消耗Ti天,每个点上有一定量的珠宝,要求必须在t天内到达终点才可以将珠宝带出去,问至多能带多少珠宝? 思路: 注意Ti可以为0,而且有可 ...

  7. HDU 4276 The Ghost Blows Light

    K - The Ghost Blows Light Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  8. BNUOJ 26283 The Ghost Blows Light

    The Ghost Blows Light Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...

  9. 树形DP(01组合背包The Ghost Blows Light HDU4276)

    题意:有n个房间,之间用n-1条道路连接,每个房间都有一个定时炸弹,在T时间后会一起爆炸,第i个房间有pi价值的珠宝,经过每条道路都需要花费一定的时间,一个人从1房间开始 ,从n房间出去,保证再不炸死 ...

随机推荐

  1. vector C++ 详细用法

    vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...

  2. bootstrap2.3.2 modal 用href时有缓存

    $('body').on('hidden', '.modal', function () {$(this).removeData('modal');}); 直接在js里加入上面的代码就可以解决缓存问题 ...

  3. 5.servlet cookie自动登录的实例

    1.要建的文档,.java用servlet创建 2.建一张登陆表格 index.jsp <%@ page language="java" import="java. ...

  4. Windows Server 2003 IIS支持ASP

    1.ASP支持是很简单的  这里简单的说一下 2.安装IIS服务   这里就不多演示了  很简单的 3.安装完成后打开IIS的扩展功能 ASP代码测试页为: <% response.write( ...

  5. Silverlight C#动态设置样式

    1.从页面资源中获取样式并应用 btnTest.Style = (Style)this.Resources["BigButtonStyle"] 2.从项目中单独分开的资源字典文件( ...

  6. 获取SilverLight.Web项目中路径Uri

    方法一: //获取指定要呈现的xaml内容的包活xaml文件Uri var strFullUrl = Application.Current.Host.Source.AbsoluteUri; if ( ...

  7. HTTP传递数据的几种方法

    Http请求的时候,需要传递参数给后端,一般都是key-value的形式,传递的方法有很多种 例如需要传递的数据是 dict(key1=value1,key2=value2) 1. URL参数 把参数 ...

  8. 【译】Android系统简介—— Activity

    续上一篇,继续介绍Android系统.上一篇: [译]Android系统简介 本文主要介绍构建Android应用的一些主要概念: Activity Activity是应用程序中一个单独的有UI的页面( ...

  9. 终于成为博客员的一员了,这是我的第一篇博文,写一个关于ul li内容宽度的问题和解决方案

    第一次写博文,写一个刚才遇到的问题吧. 关于ul li文字长度不固定,一行显示多列.当指定宽度时,文字长度超过指定的li宽度时解决方案: 如下代码 <h4>发送对象(共10个会员)< ...

  10. STL算法

    STL算法部分主要由头文 件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorit ...