1. 程式人生 > >hdu6007 Mr. Panda and Crystal 最短路+完全背包

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

cos typedef main cas int pan () 最短路 map

/**
題目: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; }

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