题目链接:​​https://www.luogu.com.cn/problem/P1432​

题目大意:经典《倒水问题》。

解题思路:虽然是经典广搜题,但是我还是跟以往一样用SPFA写通过的。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int T, A, B, N, dist[maxn][maxn], order[maxn][maxn];
pair<int, int> pre[maxn][maxn];
bool inq[maxn][maxn];
pair<int, int> get_res(int a, int b, int op) {
if (op == 1) {
return make_pair(A, b);
}
else if (op == 2) {
return make_pair(a, B);
}
else if (op == 3) {
return make_pair(0, b);
}
else if (op == 4) {
return make_pair(a, 0);
}
else if (op == 5) {
int delta = min(A-a, b);
a += delta;
b -= delta;
return make_pair(a, b);
}
else { // op == 6
int delta = min(B-b, a);
a -= delta;
b += delta;
return make_pair(a, b);
}
}
void output(int x, int y) {
if (x == 0 && y == 0) return;
output(pre[x][y].first, pre[x][y].second);
printf(" %d", order[x][y]);
}
queue<pair<int, int> > que;
void solve() { // 广搜经典题,我是用SPFA做的囧
while (!que.empty()) que.pop();
memset(dist, -1, sizeof(dist));
memset(inq, 0, sizeof(inq));
que.push(make_pair(0, 0));
dist[0][0] = 0;
while (!que.empty()) {
pair<int, int> u = que.front();
que.pop();
inq[u.first][u.second] = false;
for (int i = 1; i <= 6; i ++) {
pair<int, int> v = get_res(u.first, u.second, i);
if (dist[v.first][v.second] == -1 || dist[v.first][v.second] > dist[u.first][u.second] + 1) {
dist[v.first][v.second] = dist[u.first][u.second] + 1;
pre[v.first][v.second] = u;
order[v.first][v.second] = i;
if (!inq[v.first][v.second]) {
inq[v.first][v.second] = true;
que.push(v);
}
}
}
}
int x = -1;
for (int i = 0; i <= A; i ++) {
if (dist[i][N] != -1) {
if (x == -1 || dist[i][N] < dist[x][N]) x = i;
}
}
printf("%d", dist[x][N]);
output(x, N);
puts("");
}
int main() {
scanf("%d", &T);
while (T --) {
scanf("%d%d%d", &A, &B, &N);
solve();
}
return 0;
}