hdu6007 Mr. Panda and Crystal 最短路+完全背包

/**
题目:hdu6007 Mr. Panda and Crystal
链接:http://acm.hdu.edu.cn/showproblem.php?pid=6007
题意:魔法师有m能量,有n种宝石,有些宝石给定了用魔法变出它需要的能量,以及该宝石可以卖出的价钱。
有些宝石没有给出,给出k个方程,表示某些宝石可以通过另外一些宝石合成。
求魔法师最多可以卖出多少钱。

思路:
处理方程,最短路求出所有的宝石用能量变出的最小能量值。
然后完全背包。

*/



#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int N = 205;
const int inf = 0x3f3f3f3f;

int cost[N], price[N];
struct node
{
    int goal;
    vector<P> v;
}eq[N];
int dp[10004];
int main()
{
    int cas = 1, T, n, m, k;
    cin>>T;
    while(T--)
    {
        scanf("%d%d%d",&m,&n,&k);
        int flag;
        for(int i = 1; i <= n; i++){
            scanf("%d",&flag);
            if(flag==0){
                cost[i] = -1;
                scanf("%d",&price[i]);
            }else
            {
                scanf("%d%d",&cost[i],&price[i]);
            }
        }
        int x, y;
        for(int i = 1; i <= k; i++) eq[i].v.clear();
        for(int i = 1; i <= k; i++){
            scanf("%d%d",&x,&y);
            eq[i].goal = x;
            int u, vv;
            for(int j = 1; j <= y; j++){
                scanf("%d%d",&u,&vv);
                eq[i].v.push_back(P(u,vv));
            }
        }
        while(1)
        {
            int flag = 1;
            for(int i = 1; i <= k; i++){
                int sign = 1;
                int sum = 0;
                for(int j = 0; j < (int)(eq[i].v.size()); j++){
                    P p = eq[i].v[j];
                    if(cost[p.first]==-1){
                        sign = 0; break;
                    }else
                    {
                        sum += cost[p.first]*p.second;
                        if(sum>m){///完全背包,最多m容量,所以超过m的能量花费,都不会被使用。这样避免溢出。
                            sum = m+1; break;
                        }
                    }
                }
                if(sign){
                    if(cost[eq[i].goal]!=-1){
                        if(cost[eq[i].goal]>sum){
                            cost[eq[i].goal] = sum;
                            flag = 0;
                        }
                    }else
                    {
                        cost[eq[i].goal] = sum;
                        flag = 0;
                    }
                }
            }
            if(flag) break;
        }
        memset(dp, 0, sizeof dp);
        for(int i = 1; i <= n; i++){
            if(cost[i]==-1) continue;
            for(int j = cost[i]; j <= m; j++){
                dp[j] = max(dp[j],dp[j-cost[i]]+price[i]);
            }
        }
        printf("Case #%d: %d\n",cas++,dp[m]);
    }
    return 0;
}

 

posted on 2017-07-26 20:28  hnust_accqx  阅读(161)  评论(0编辑  收藏  举报

导航