UVA 10603 FILL

来源:互联网 发布:list<map>转json 编辑:程序博客网 时间:2024/06/01 21:53

搜索不局限于图、迷宫,凡用状态来表示的,通常都可用。

故记录此题。

hint:由于此题答案求倒水量最少,而非倒水次数最少,因此,用优先队列来存储状态,比较的依据也是各状态的倒水量。如果是一般的求倒水步数,那就是一般的队列。



#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<queue>using namespace std;const int maxn=205;int vis[maxn][maxn],ans[maxn],cap[3];struct Node{    int v[3],used;    bool operator < (const Node& rhs) const{        return used>rhs.used;    }};void update_ans(const Node& u){    for(int i=0;i<3;i++){        int d=u.v[i];        if(ans[d]<0||u.used<ans[d]) ans[d]=u.used;    }}void solve(int a,int b,int c,int d){    cap[0]=a;cap[1]=b;cap[2]=c;    memset(vis,0,sizeof(vis));    memset(ans,-1,sizeof(ans));    priority_queue<Node> q;    Node init;    init.used=0;    init.v[0]=init.v[1]=0;    init.v[2]=c;    q.push(init);    vis[0][0]=1;    while(!q.empty()){        Node u=q.top();        q.pop();        update_ans(u);//update ans        if(ans[d]>0) break;//ans[d]>0:got answer        for(int i=0;i<3;i++)            for(int j=0;j<3;j++)                if(i!=j){                    if(u.v[i]==0||u.v[j]==cap[j]) continue;                    int use=min(cap[j],u.v[i]+u.v[j])-u.v[j];                    Node r;                    memcpy(&r,&u,sizeof(u));                    r.used+=use;                    r.v[i]-=use;                    r.v[j]+=use;                    if(vis[r.v[0]][r.v[1]]!=1){                        q.push(r);                        vis[r.v[0]][r.v[1]]=1;                    }                }    }    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--){        cin>>a>>b>>c>>d;        solve(a,b,c,d);    }    return 0;}
mark:代码中,更新ans的条件,要么这个倒水量之前没达到过,要么更少的排水量出现。

原创粉丝点击