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)的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 10603 Fill(隐式图搜索)

[UVa 10603] Fill

UVa 10603 Fill [暴力枚举路径搜索]

UVa10603 倒水 Fill-状态空间搜索

倒水问题 (FillUVa 10603) 隐式图

UVA10603Fill题解--BFS