知识点:BFS,最短路,图论建模
这个题其实就是最短路问题,关键是要建立图论模型,然后这个题就好做了,但是怎么想到建立最短路模型的那就只能多做题了,这个题的关键点除了建立图论模型之外,还有一个就是状态,一开始选择状态是3元组,但是根据题意,几个杯子倒水的时候,水是不会洒到外面的,所以水的总数是相同的,那么其实状态是二维的就可以了,数组一开始开的3维的大小,结果超时,改成二维的就过了,这个情况还是第一次遇到,查找原因只能是多组数据,这是需要注意的一个点
#include <bits/stdc++.h>
using namespace std;
const int N = 205;
const int INF = 0x7fffffff;
struct state {
int w[3], cost;
state() {}
state(int a, int b, int c, int d) {
w[0] = a; w[1] = b; w[2] = c; cost = d;
}
bool operator < (const state &t) const {
return cost > t.cost;
}
};
int a[3], d, h[N][N], Min, ans;
void bfs() {
memset(h, 0, sizeof(h));
priority_queue<state> q;
q.push(state(0, 0, a[2], 0));
while (!q.empty()) {
state now = q.top(); q.pop();
if (h[now.w[0]][now.w[1]]) continue;
for (int i = 0; i < 3; i++) {
if (now.w[i] <= d && d - now.w[i] < Min) {
Min = min(Min, d - now.w[i]);
ans = now.cost;
}
if (now.w[i] == d) return;
}
h[now.w[0]][now.w[1]] = 1;
for (int i = 0; i < 3; i++) {
if (!now.w[i]) continue;
for (int j = 0; j < 3; j++) {
if (i == j || now.w[j] == a[j]) continue;
state cur = now;
if (now.w[i] >= a[j] - now.w[j]) {
cur.w[i] -= a[j] - now.w[j];
cur.w[j] = a[j];
cur.cost += a[j] - now.w[j];
} else {
cur.w[i] = 0;
cur.w[j] += now.w[i];
cur.cost += now.w[i];
}
if (h[cur.w[0]][cur.w[1]]) continue;
q.push(cur);
}
}
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
Min = INF;
scanf("%d%d%d%d", &a[0], &a[1], &a[2], &d);
bfs();
printf("%d %d\n", ans, d - Min);
}
return 0;
}