zoukankan      html  css  js  c++  java
  • HDU4276 The Ghost Blows Light SPFA&&树dp

    题目的介绍以及思路完全参考了下面的博客: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
    ", dp[1][t]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ansible常用模块及参数(1)
    ansible搭建wordpress,安装nfs和rsync
    ElasticSearch 集群
    kibana数据操作
    ElasticSearch 交互使用
    Elasticsearch的基础安装
    Elasticsearch的简介
    redis数据审计
    redis数据迁移
    redis集群节点添加与删除
  • 原文地址:https://www.cnblogs.com/chanme/p/3567172.html
Copyright © 2011-2022 走看看