UVA - 658_It's not a Bug, it's a Feature! (用map超时,改用位运算完美哈希)
#include<bits/stdc++.h> using namespace std; typedef pair<int,string>Pair; const int maxn = 20 + 3; const int maxm = 100 + 3; int n, m; struct Edge{ string u, v; int w; Edge(string u, string v, int w):u(u), v(v), w(w){} }; vector<Edge>edges; map<string,int>d; bool canFix(string &bug, string &patch) { for(int i = 0; i < n; i++){ if(patch[i] != '0' && patch[i] != bug[i]) return false; } return true; } int dijkstra() { string source(n, '+'); string target(n, '-'); priority_queue<Pair, vector<Pair>, greater<Pair>>pq; pq.push(make_pair(0, source)); d[source] = 0; while(!pq.empty()){ Pair u = pq.top(); pq.pop(); if(u.second == target){ return u.first; } if(u.first != d[u.second]) continue; for(int i = 0; i < m; i++){ if(canFix(u.second, edges[i].u)){ Pair v(0,u.second); for(int j = 0; j < n; j++){ if(edges[i].v[j] != '0') v.second[j] = edges[i].v[j]; } if(!d.count(v.second) || d[v.second] > d[u.second] + edges[i].w){ d[v.second] = d[u.second] + edges[i].w; v.first = d[v.second]; pq.push(v); } } } } return -1; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int kase = 0; while(cin >> n >> m && n){ edges.clear(); d.clear(); for(int i = 0; i < m; i++){ string u, v; int w; cin >> w >> u >> v; edges.push_back(Edge(u, v, w)); } int ans = dijkstra(); cout << "Product " << ++kase << endl; if(ans == -1) cout << "Bugs cannot be fixed.\n"; else cout << "Fastest sequence takes " << ans << " seconds.\n"; cout << endl; } return 0; } /* 3 3 1 000 00- 1 00- 0-+ 2 0-- -++ 4 1 7 0-0-+ ---- */
用map超时。
#include<bits/stdc++.h> using namespace std; typedef pair<int,int>Pair; const int maxn = 20; const int maxm = 100 + 3; int n, m; struct Edge{ string u, v; int w; Edge(string u, string v, int w):u(u), v(v), w(w){} }; vector<Edge>edges; //map<string,int>d; int d[1<<maxn]; bool canFix(string &bug, string &patch) { for(int i = 0; i < n; i++){ if(patch[i] != '0' && patch[i] != bug[i]) return false; } return true; } int dijkstra() { //string source(n, '+'); //string target(n, '-'); priority_queue<Pair, vector<Pair>, greater<Pair>>pq; pq.push(make_pair(0, (1<<n)-1)); //2^n - 1,全1即全+,即用1代表+,0代表-,来作为string到int的映射。 for(int i = 0; i < (1<<n); i++) d[i] = INT_MAX; d[(1<<n)-1] = 0; while(!pq.empty()){ Pair u = pq.top(); pq.pop(); if(u.second == 0){ return u.first; } if(u.first != d[u.second]) continue; for(int i = 0; i < m; i++){ bool ok = 1; for(int j = 0; j < n; j++){ if(edges[i].u[j] == '+' && !(u.second & (1<<j))){ ok = 0; break; }else if(edges[i].u[j] == '-' && (u.second & (1<<j))){ ok = 0; break; } } if(ok){ Pair v(0,u.second); for(int j = 0; j < n; j++){ if(edges[i].v[j] == '+'){ //v的j位设为1 v.second |= (1<<j); }else if(edges[i].v[j] == '-'){ v.second &= ~(1<<j); } } if(d[v.second] == INT_MAX || u.first + edges[i].w < d[v.second]){ d[v.second] = u.first + edges[i].w; v.first = d[v.second]; pq.push(v); } } } } return -1; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int kase = 0; while(cin >> n >> m && n){ edges.clear(); for(int i = 0; i < m; i++){ string u, v; int w; cin >> w >> u >> v; edges.push_back(Edge(u, v, w)); } int ans = dijkstra(); cout << "Product " << ++kase << endl; if(ans == -1) cout << "Bugs cannot be fixed.\n"; else cout << "Fastest sequence takes " << ans << " seconds.\n"; cout << endl; } return 0; } /* 3 3 1 000 00- 1 00- 0-+ 2 0-- -++ 4 1 7 0-0-+ ---- */
位运算完美哈希,AC。
收获:
1. 善于利用位运算技巧。比如将某位置一或0。
2. 从题目规模中寻求最好的方法。像这里,n最大为20,百万级别的存储量是可以在全局空间开辟的。