您的位置:首页 > 其它

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

2017-07-26 20:28 351 查看
/**
题目: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
, price
;
struct node
{
int goal;
vector<P> v;
}eq
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: