洛谷P1432 倒水问题 题解 广搜经典入门题(SPFA求解)

题目链接: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;
}
posted @ 2020-01-29 20:14  quanjun  阅读(343)  评论(0编辑  收藏  举报