Fill UVa 10603 BFS优先队列

思路:紫书上的思路 主要是优先队列BFS  结构体的运算符重载需要注意,还有具体不足D的写法也要注意

#include<bits/stdc++.h>
using namespace std;
int cap[3];
int  dis[210][210], mark[210][210],vis[210][210];
int ans[210];

struct Node{
int v[3],dis;
bool operator<(const Node&b)const {//两个const 及大于小于号需要注意
return dis>b.dis;
}
};

void update_ans(Node&u){
for(int i=0;i<3;i++){
    if(ans[u.v[i]]<0||u.dis<ans[u.v[i]])ans[u.v[i]]=u.dis;
}

}

void solve(int a,int b,int c,int d){
cap[0]=a; cap[1]=b;cap[2]=c;
memset(mark,0,sizeof(mark));  //记录是否访问过
memset(ans,-1,sizeof(ans));   //记录and[d],d容量时倒水量最少的值
memset(dis,-1,sizeof(dis));   //记录dis[a][b],第一个,第二个水量分别为a,b时最小的到水量,用于后面剪枝
Node start;
start.v[0]=0;start.v[1]=0;start.v[2]=c;
start.dis=0;
priority_queue<Node>q;
q.push(start);
dis[0][0]=0;
while(!q.empty()){
    Node u=q.top();
    q.pop();
    if(mark[u.v[0]][u.v[1]])continue;        
    mark[u.v[0]][u.v[1]]=1;
    update_ans(u);
    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 amount=min(cap[j],u.v[i]+u.v[j])-u.v[j]; 
            Node temp=u;
            temp.v[i]-=amount;
            temp.v[j]+=amount;
            temp.dis+=amount;
            int&D=dis[temp.v[0]][temp.v[1]];
            if(D<0||temp.dis<D){
                D=temp.dis;
                q.push(temp);
            }

        }
    }

}
while(d>=0){
    if(ans[d]>=0){
        printf("%d %d\n",ans[d],d); //找出用水量最少的最接近D的值
        break;
    }
    d--;
}



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

猜你喜欢

转载自blog.csdn.net/Bug___Maker/article/details/81096086