uva10603 BFS


倒水问题,不是很能理解为什么刘汝佳的蓝书把该题归类为最短路。

简单的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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值