倒水问题,不是很能理解为什么刘汝佳的蓝书把该题归类为最短路。
简单的BFS,注意用优先队列。
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int maxn = 200+5;
struct node{
int water,va,vb,vc;
bool operator <(const node &rhs) const {
return water>rhs.water;
}
}p,q;
int a,b,c,d,volume;
priority_queue<node>que;
bool vis[maxn][maxn][maxn];
int ans,d1;
inline int Min(int x, int y) {return x<y?x:y;}
inline int Max(int x, int y) {return x>y?x:y;}
void BFS(){
p.water = 0; p.va = 0; p.vb = 0; p.vc = c;
d1 = ans = 0; que.push(p);
int tmp;
while (!que.empty()){
p = que.top(); que.pop();
if (vis[p.va][p.vb][p.vc]) continue;
vis[p.va][p.vb][p.vc] = 1;
if (p.va == d || p.vb == d || p.vc == d) {
ans = p.water;
d1 = d;
return ;
}
else {
if (p.va<d && p.va > d1) {ans = p.water; d1 = p.va;}
if (p.vb<d && p.vb > d1) {ans = p.water; d1 = p.vb;}
if (p.vc<d && p.vc > d1) {ans = p.water; d1 = p.vc;}
}
if (p.va) {
if (p.vb < b) {
tmp = b - p.vb; tmp = Min(tmp,p.va);
q.water = p.water+tmp;
q.va = p.va-tmp; q.vb = tmp+p.vb; q.vc = p.vc;
que.push(q);
}
if (p.vc < c) {
tmp = c - p.vc; tmp = Min(tmp,p.va);
q.water = p.water+tmp;
q.va = p.va-tmp; q.vb = p.vb; q.vc = p.vc+tmp;
que.push(q);
}
}
if (p.vb) {
if (p.va < a) {
tmp = a - p.va; tmp = Min(tmp,p.vb);
q.water = p.water+tmp;
q.va = p.va+tmp; q.vb = p.vb-tmp; q.vc = p.vc;
que.push(q);
}
if (p.vc < c) {
tmp = c - p.vc; tmp = Min(tmp,p.vb);
q.water = p.water+tmp;
q.va = p.va; q.vb = p.vb-tmp; q.vc = p.vc+tmp;
que.push(q);
}
}
if (p.vc) {
if (p.va < a) {
tmp = a - p.va; tmp = Min(tmp,p.vc);
q.water = p.water+tmp;
q.va = p.va+tmp; q.vb = p.vb; q.vc = p.vc-tmp;
que.push(q);
}
if (p.vb < b) {
tmp = b - p.vb; tmp = Min(tmp,p.vc);
q.water = p.water+tmp;
q.va = p.va; q.vb = p.vb+tmp; q.vc = p.vc-tmp;
que.push(q);
}
}
}
}
int main(){
int T;
scanf("%d",&T);
while (T--){
scanf("%d %d %d %d",&a,&b,&c,&d);
memset(vis,0,sizeof(vis));
while (!que.empty()) que.pop();
volume = c;
BFS();
printf("%d %d\n",ans,d1);
}
return 0;
}