Question: Question Link
Idea: it is not difficult to see that the synthesis of each gem consumes a certain amount of magic, each gem has a certain benefit, so as long as we know the minimum cost of each gem synthesis, this problem can be converted into a full backpack with the initial magic value. The minimum cost of each gem can be calculated by running Dijkstra once and then the shortest path length is expressed by the synthetic cost.
AC code:
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 }
Mr. Panda and crystal HDU-6007 short circuit + full backpack