UVa10603 Fill (隐式图搜索+Dijkstra)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa10603 Fill (隐式图搜索+Dijkstra)相关的知识,希望对你有一定的参考价值。
链接:http://acm.hust.edu.cn/vjudge/problem/19527
分析:隐式图搜索,从初始状态(0,0,c)开始,维护一个到达k升水所需的最少倒水量ans。结点状态设计为v[3]表示当前状态三个杯子中的水量和到达此状态的倒水量。用一个二维vis判重,因为只要第1,2个杯子里的水量确定第3个杯子里的水量也就确定了,所以二维就足以表示了。然后跑一边Dijkstra,用优先队列每次取出倒水量最少的的结点进行扩展,然后用到了一个定序的技巧,规定从i号杯子倒到j号杯子里,生成一个新的结点,维护v和dist,判重后加入队列中。最后打印输出d或d‘。
1 #include <cstdio> 2 #include <queue> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 7 struct Node { 8 int v[3], dist; 9 bool operator < (const Node& rhs) const { 10 return dist > rhs.dist; 11 } 12 }; 13 14 int const maxn = 200 + 5; 15 int a, b, c, d, cap[3], vis[maxn][maxn], ans[maxn]; 16 17 void update_ans(const Node& u) { 18 for (int i = 0; i < 3; i++) { 19 int d = u.v[i]; 20 if (ans[d] < 0 || u.dist < ans[d]) ans[d] = u.dist; 21 } 22 } 23 24 void solve() { 25 cap[0] = a; cap[1] = b; cap[2] = c; 26 memset(vis, 0, sizeof(vis)); 27 memset(ans, -1, sizeof(ans)); 28 priority_queue<Node> q; 29 30 Node start; 31 start.dist = 0; 32 start.v[0] = 0; start.v[1] = 0; start.v[2] = c; 33 vis[0][0] = 1; 34 q.push(start); 35 36 while (!q.empty()) { 37 Node u = q.top(); q.pop(); 38 update_ans(u); 39 if (ans[d] >= 0) break; 40 for (int i = 0; i < 3; i++) 41 for (int j = 0; j < 3; j++) if (i != j) { 42 if (u.v[i] == 0 || u.v[j] == cap[j]) continue; 43 int amount = min(cap[j], u.v[i] + u.v[j]) - u.v[j]; 44 Node u2; 45 memcpy(&u2, &u, sizeof(u)); 46 u2.dist = u.dist + amount; 47 u2.v[i] -= amount; 48 u2.v[j] += amount; 49 if (!vis[u2.v[0]][u2.v[1]]) { 50 vis[u2.v[0]][u2.v[1]] = 1; 51 q.push(u2); 52 } 53 } 54 } 55 while (d >= 0) { 56 if (ans[d] >= 0) { 57 printf("%d %d\n", ans[d], d); 58 return; 59 } 60 d--; 61 } 62 } 63 64 int main() { 65 int T; 66 scanf("%d", &T); 67 while (T--) { 68 scanf("%d%d%d%d", &a, &b, &c, &d); 69 solve(); 70 } 71 return 0; 72 }
以上是关于UVa10603 Fill (隐式图搜索+Dijkstra)的主要内容,如果未能解决你的问题,请参考以下文章