• 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;
    }
  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12363490.html
Copyright © 2020-2023  润新知