Mr. Panda and Crystal HDU - 6007 最短路+完全背包

题目:题目链接

思路:不难看出,合成每个宝石需要消耗一定的魔力值,每个宝石有一定的收益,所以只要我们知道每个宝石合成的最小花费,该题就可以转化为一个背包容量为初始魔力值的完全背包问题,每个宝石的最小花费可以用dijkstra跑一遍最短路算出,路径长度用合成花费表示。

AC代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <vector>
  6 #include <queue>
  7 
  8 using namespace std;
  9 
 10 const int maxn = 10000 + 5;
 11 
 12 int vol, n, m, INF;
 13 
 14 struct node {
 15     int c, w;
 16     vector<int> v;
 17     vector<vector<pair<int, int> > > vec;
 18     friend bool operator < (node a, node b) {
 19         return a.w > b.w;
 20     }
 21 }gem[maxn];
 22 
 23 priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> > q;
 24 
 25 bool vis[maxn];
 26 
 27 void init() {
 28     for(int i = 1; i <= n; ++i) {
 29         for(int j = 0; j < gem[i].vec.size(); ++j)
 30             gem[i].vec[j].clear();
 31         gem[i].vec.clear();
 32         gem[i].v.clear();
 33     }
 34     while(!q.empty()) 
 35         q.pop();
 36     memset(vis, false, sizeof(vis));
 37 }
 38 
 39 bool get_sum(int id) {
 40     int sum, _min = INF;
 41     for(int i = 0; i < gem[id].vec.size(); ++i) {
 42         sum = 0;
 43         for(int j = 0; j < gem[id].vec[i].size(); ++j) {
 44             sum += gem[gem[id].vec[i][j].first].c * gem[id].vec[i][j].second;
 45             if(sum > INF)
 46                 sum = INF;
 47         }
 48         _min = min(_min, sum);
 49     }
 50     if(_min < gem[id].c) {
 51         gem[id].c = _min; 
 52         return true;
 53     }
 54     return false;
 55 }
 56 
 57 void dijkstra() {
 58     while(!q.empty()) {
 59         pair<int, int> P = q.top();
 60         q.pop();
 61         if(vis[P.second])
 62             continue;
 63         vis[P.second] = true;
 64         for(int i = 0; i < gem[P.second].v.size(); ++i) {
 65             if(!vis[gem[P.second].v[i]] && get_sum(gem[P.second].v[i])) {
 66                 q.push(make_pair(gem[gem[P.second].v[i]].c, gem[P.second].v[i]));
 67             }
 68         }
 69     }
 70 }
 71 
 72 int dp[maxn];
 73 
 74 int main()
 75 {
 76     ios::sync_with_stdio(0);
 77     cin.tie(0);
 78 
 79     int T, t = 0;
 80     cin >> T;
 81     while(T--) {
 82         cin >> vol >> n >> m;
 83         INF = vol + 1;
 84         init();
 85         int flag;
 86         for(int i = 1; i <= n; ++i) {
 87             cin >> flag;
 88             if(flag)
 89                 cin >> gem[i].c >> gem[i].w;
 90             else {
 91                 cin >> gem[i].w;
 92                 gem[i].c = INF;
 93             }
 94         }
 95         int id, num, c, nu;
 96         vector<pair<int, int> > ope;
 97         for(int i = 0; i < m; ++i) {
 98             cin >> id >> num;
 99             ope.clear();
100             for(int j = 0; j < num; ++j) {
101                 cin >> c >> nu;
102                 ope.push_back(make_pair(c, nu));
103                 gem[c].v.push_back(id);
104             }
105             gem[id].vec.push_back(ope);
106         }
107 
108         for(int i = 1; i <= n; ++i) 
109             if(gem[i].c < INF)
110                 q.push(make_pair(gem[i].c, i));
111 
112         dijkstra();
113 
114         memset(dp, 0, sizeof(dp));
115         for(int i = 1; i <= n; ++i) 
116             for(int v = 0; v <= vol; ++v)
117                 if(v >= gem[i].c)
118                     dp[v] = max(dp[v], dp[v - gem[i].c] + gem[i].w);
119     
120         cout << "Case #" << ++t << ": " << dp[vol] << endl;
121     }
122     return 0;
123 }

 

posted @ 2018-10-04 19:29  FanJiaming  阅读(220)  评论(0编辑  收藏  举报