zoukankan      html  css  js  c++  java
  • The Ghost Blows Light

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4276

    题意:

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

    思路:

    我们首先考虑直接从1->n走的路径是必须要走的,我们先统计出这个的价值和时间。

    如果时间允许的话,那么除这些路径以外的所有路径都是需要走两遍的,这就像之前一道题允许重复走所获的的最大价值一样了

    f[u][j] u为根结点时间为j的时候允许获得的最大价值

    转移方程:

    f[u][j] = max(f[u][j],f[u][j-k]+f[v][k-2*w] )   (w是 u->v 的边权)

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    const double eps = 1e-10;
    const int maxn = 100 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    struct edge {
        int v,w,nxt;
    }e[maxn<<1];
    
    int head[maxn];
    int f[maxn][510],w[maxn];
    int cnt;
    int n,m,sum;
    
    inline void add_edge(int u,int v,int w) {
        e[++cnt].v = v;
        e[cnt].w = w;
        e[cnt].nxt = head[u];
        head[u] = cnt;
    }
    
    inline bool get_sum(int x,int fa) {
        if (x == n)
            return true;
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            if (v == fa)
                continue;
            if (get_sum(v,x)) {
                sum += e[i].w;
                e[i].w = 0;
                return true;
            }
        }
        return false;
    }
    
    inline void dfs(int x,int fa) {
        for (int i = head[x];~i;i = e[i].nxt) {
            int v = e[i].v;
            if (v == fa)
                continue;
            dfs(v,x);
            for (int j = m;j >= 0;j--) {
                for (int k = 2*e[i].w;k <= j;k++)
                    f[x][j] = max(f[x][j],f[x][j-k]+f[v][k-2*e[i].w]);
            }
        }
    }
    
    
    
    
    int main() {
        while (cin >> n >> m) {
            sum = 0;
            cnt = 0;
            memset(f,0, sizeof(f));
            memset(head,-1, sizeof(head));
            for (int i = 1;i < n;i++) {
                int a,b,c;
                cin >> a >> b >> c;
                add_edge(a,b,c);
                add_edge(b,a,c);
            }
            for (int i = 1;i <= n;i++)
                cin >> w[i];
            for (int i = 1;i <= n;i++) {
                for (int j = 0;j <= m;j++)
                    f[i][j] = w[i];
            }
            get_sum(1,0);
            m -= sum;
            if (m < 0) {
               cout << "Human beings die in pursuit of wealth, and birds die in pursuit of food!" << endl;
                continue;
            }
            dfs(1,0);
            cout << f[1][m] << endl;
        }
        return 0;
    }
  • 相关阅读:
    【C++】对象模型
    【C++多线程】读写锁shared_lock/shared_mutex
    【C++多线程】共享数据的初始化保护
    【C++多线程】共享数据保护
    【C++多线程】lock_guard<T>类和unique_lock<T>类
    【C++多线程】转移线程所有权
    【C++ 】std::ref()和std::cref()
    【C++多线程】传递参数
    【C++多线程】detach()及注意
    linux 打开CHM文件
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12363490.html
Copyright © 2011-2022 走看看