• 状态空间搜索好题UVA10603


    题目

    分析:注意这里求的是最少流量, 二不是最少步数!!!所以我们用优先队列去维护一个最小流量,然后进行bfs即可,解释一下一个重要的数组ans[i],表示的是杯子中的水为i时的最小流量

     1 #include "iostream"
     2 #include "cstdio"
     3 #include "cstring"
     4 #include "queue"
     5 #include "algorithm"
     6 using namespace std;
     7 const int maxn=200+10;
     8 int a,b,c,d,T;
     9 int vis[maxn][maxn],ans[maxn],cap[3];  //ans[i]表示杯子中有i升水时对应的最少倒水量
    10 struct Node{
    11     int v[3],dist;
    12     bool operator < (const Node & rsh) const{  //小顶堆
    13         return dist>rsh.dist; 
    14     }
    15 };
    16 
    17 void update(const Node & u){   //更新ans[]
    18     for(int i=0;i<3;i++){
    19         int s=u.v[i];
    20         if(ans[s]<0||u.dist<ans[s])  ans[s]=u.dist;
    21     }
    22 }
    23 
    24 void bfs(int a,int b,int c,int d){
    25     memset(vis,0,sizeof(vis));
    26     memset(ans,-1,sizeof(ans));
    27     cap[0]=a,cap[1]=b,cap[2]=c;
    28     Node start;
    29     start.dist=0;
    30     start.v[0]=0,start.v[1]=0,start.v[2]=c;
    31     priority_queue<Node>que;
    32     vis[0][0]=1;
    33     que.push(start);
    34     while(!que.empty()){
    35         Node u=que.top(); que.pop();
    36         update(u);
    37         if(ans[d]>=0)  break;   //如果找到了
    38         for(int i=0;i<3;i++){
    39             for(int j=0;j<3;j++) if(i!=j){   //自己不能和自己匹配
    40                 if(u.v[i]==0||u.v[j]==cap[j])   continue;  
    41                 int num=min(cap[j],u.v[i]+u.v[j])-u.v[j];
    42                 Node u2;
    43                 memcpy(&u2,&u,sizeof(u));
    44                 u2.v[i]-=num;
    45                 u2.v[j]+=num;
    46                 u2.dist=u.dist+num;
    47                 if(!vis[u2.v[0]][u2.v[1]]){  //如果当前状态没有出现过
    48                     vis[u2.v[0]][u2.v[1]]=1;
    49                     que.push(u2);
    50                 }
    51             }
    52         }
    53     }
    54     while(d>=0){
    55         if(ans[d]>=0){
    56             printf("%d %d
    ",ans[d],d);
    57             return ;
    58         }
    59         --d;
    60     }
    61 }
    62 int main()
    63 {
    64     scanf("%d",&T);
    65     while(T--){
    66         scanf("%d%d%d%d",&a,&b,&c,&d);
    67         bfs(a,b,c,d);
    68     }
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    Android ContentProvider和getContentResolver
    onContextItemSelected 用法
    Android 控件 之 Menu 菜单
    Android
    Android Cursor类的概念和用法
    android SQLiteOpenHelper使用示例
    JAVA HashMap详细介绍和示例
    HashMap深度解析(二)
    HashMap深度解析(一)
    使用svn遇到的问题---(在编辑器没有配置svn的前提下)
  • 原文地址:https://www.cnblogs.com/wolf940509/p/6741074.html
Copyright © 2020-2023  润新知