UVA 10603 Fill Water BFS

版权声明:转载标注来源喔~ https://blog.csdn.net/iroy33/article/details/89341674

UVA10603

并没有A。。。但注释大概还是可以给搭嘎提供点思路的

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdio>
using namespace std;
struct Node
{
    int v[3],dist; //dist该状态倒出的水量,v[3]记录每个杯子里的水量
    bool operator<(const Node &rs)const
    {
        return dist>rs.dist;         //
    }
};
const int N=210;
bool vis[N][N];     //i,j代表第0个杯子和第1个杯子的剩余水量,因为知道总和,所以可以用两个杯子的剩余水量来代表三个杯子
int cap[3];
int ans[N];     //得到水量i需要倒出的最小水量ans[i]   目标求得ans[d]
void update_ans(const Node& u)//可以获得状态u下三个杯子里水量的水
{
    for(int i=0;i<3;++i)
    {
        int k=u.v[i];
        if(ans[k]<0||u.dist<ans[k]) ans[k]=u.dist;
    }

}
void solve(int a,int b,int c,int d)
{
    memset(ans,-1,sizeof(ans));
    memset(vis,false,sizeof(vis));
    cap[0]=a;cap[1]=b;cap[2]=c;
    Node s;
    s.v[0]=0;s.v[1]=0;s.v[2]=c;s.dist=0;
    priority_queue<Node> q;
    q.push(s);
    vis[a][b]=true;
    while(!q.empty())
    {
        Node tmp=q.top();
        q.pop();
        update_ans(tmp);
        if(ans[d]>=0) break;   //目标水量已获得  否则的话开始倒水
        for(int i=0;i<3;++i)  //从i向j倒水
            for(int j=0;j<3;++j)
            {
                if(i==j) continue;
                if(!tmp.v[i]||tmp.v[j]==cap[j]) continue;   //i是空的或者j是满的
                int amount=min(cap[j],tmp.v[i]+tmp.v[j])-tmp.v[j];//如果i杯和j杯剩的水加起来没有cap[j]大,那么能增加的水就是v[i]
                //否则能增加的水就是cap[j]-v[j]
                Node u;
                memcpy(&u,&tmp,sizeof(tmp));
                u.v[i]-=amount;
                u.v[j]+=amount;
                u.dist=tmp.dist+amount;
                if(!vis[u.v[0]][u.v[1]])
                {
                    q.push(u);
                    vis[u.v[0]][u.v[1]]=true;
                }
            }
    }
//    cout<<d<<endl;
//    cout<<ans[d]<<endl;
    while(d>=0)
    {
        if(ans[d]>=0) {printf("%d %d\n",ans[d],d); return;}
        d--;
    }

}
int main()
{
    int T,a,b,c,d;
    scanf("%d",&T);
    while(T--)
    {
       scanf("%d%d%d%d",&a,&b,&c,&d);
        solve(a,b,c,d);
    }
    return 0;

}

猜你喜欢

转载自blog.csdn.net/iroy33/article/details/89341674