1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <queue>
const int MAXM = 100 + 10; const int MAX_NODE = (1 << 22);
int n, m;
struct Patch { int usage; int required, requiredNot; int fixedBugs, newBugs;
Patch(int _us = 0, int _r = 0, int _rn = 0, int _f = 0, int _n = 0) : usage(_us), required(_r), requiredNot(_rn), fixedBugs(_f), newBugs(_n) {} void read() { std::string requireStr, effectStr; std::cin >> usage >> requireStr >> effectStr; for (int i = 0; i < n; ++i) { if (requireStr[i] == '+') required += (1 << (i)); else if (requireStr[i] == '-') requiredNot += (1 << (i)); if (effectStr[i] == '-') fixedBugs += (1 << (i)); else if (effectStr[i] == '+') newBugs += (1 << (i)); } } } patches[MAXM];
struct Node { int id, wt; Node(int _i = 0, int _w = 0) : id(_i), wt(_w) {} bool operator < (const Node &that) const { return wt > that.wt; } };
int dist[MAX_NODE]; bool vis[MAX_NODE];
int getInstallResult(int id, Patch p) { if ((id | p.required) != id) return -1; if ((id & p.requiredNot) != 0) return -1; int res = (((id | p.fixedBugs) ^ p.fixedBugs) | p.newBugs); return res; }
void shortestPath() { std::priority_queue<Node> q; int init = ((1 << n) - 1); while (!q.empty()) q.pop(); q.push(Node(init, 0)); memset(dist, 0x3f, sizeof dist); dist[init] = 0; while (!q.empty()) { Node nownode = q.top(); q.pop(); int u = nownode.id; if (vis[u]) continue; vis[u] = true; for (int i = 1; i <= m; ++i) { int res = getInstallResult(u, patches[i]); if (res == -1) continue; if (dist[res] > dist[u] + patches[i].usage) { dist[res] = dist[u] + patches[i].usage; q.push(Node(res, dist[res])); } } } }
int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; ++i) { patches[i].read(); } shortestPath(); if (dist[0] != 0x3f3f3f3f) printf("%d\n", dist[0]); else puts("0"); return 0; }
|