倒水问题 (FillUVa 10603) 隐式图

题意:本题的题意是给你三个杯子,第一二个杯子是空的,第三个杯子装满水,要求是量出一定容量d升的水。若是得不到d升的水,那就让某一个杯子里面的水达到d‘,使得d'尽量接近d升。
解题思路:本题是给出初始状态,让你寻找一条通往目标的路径,此题也可看成是有向图中在起点和目标点之间寻找一条最短路径,但是这个最短路径不是距离最短而是倒的水最少,所以这题类似于Dijkstra算法求最短路,利用广搜,一直选当前水量最少的结点进行扩展,所以可以建立一个优先队列来存储下一次要访问的结点,同时将访问过的结点标记一下,大大节省了访问时间,此题的结点数最多为201^2.
代码:
#include<stdio.h>
#include<math.h>
#include<queue>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn=;
int n;
int visit[maxn][maxn],cap[],ans[maxn];
//三个数组分别表示标记是否访问过这种情况,三个容器的大小,以及得到对应的水需要倒水的体积 struct Node{
int v[],dist;
const bool operator < (Node s) const{ //优先队列重载运算符
return dist>s.dist;
}
}; void update(Node t){ //更新倒水数
for(int i=;i<;i++){
int s=t.v[i];
if(ans[s]< || t.dist<ans[s]){
ans[s]=t.dist;
}
}
} void traver(int a,int b,int c,int d){ //遍历函数
priority_queue<Node> q;
memset(visit,,sizeof(visit));
memset(ans,-,sizeof(ans));
cap[]=a;
cap[]=b;
cap[]=c;
Node s;
s.v[]=;
s.v[]=;
s.v[]=c;
s.dist=;
q.push(s);
visit[][]=;
while(!q.empty()){
Node t=q.top();
q.pop();
update(t);
if(ans[d]>=) break;
for(int i=;i<;i++){//访问下一个结点,表示将水从i杯倒到j杯
for(int j=;j<;j++){
if(i!=j){
if(t.v[i]==||t.v[j]==cap[j]) continue;
Node k;
int water=min(t.v[i],cap[j]-t.v[j]);
k.dist=t.dist+water;
k.v[i]=t.v[i]-water;
k.v[j]=t.v[j]+water;
k.v[-i-j]=t.v[-i-j]; //如果不是讲原结点复制过来的,记得给此结点赋值
if(!visit[k.v[]][k.v[]]){
visit[k.v[]][k.v[]]=;
q.push(k);
}
}
}
}
}
for(;d>=;d--){ //输出
if(ans[d]>=){
printf("%d %d\n",ans[d],d);
break;
}
}
} int main(){
freopen("in.txt","r",stdin);
scanf("%d",&n);
while(n--){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
traver(a,b,c,d);
}
return ;
}
倒水问题 (FillUVa 10603) 隐式图的更多相关文章
- 倒水问题UVA 10603——隐式图&&Dijkstra
题目 给你三个容量分别为 $a,b,c$ 的杯子,最初只有第3个杯子装满了水,其他两个杯子为空.最少需要到多少水才能让一个某个杯子中的水有 $d$ 升呢?如果无法做到恰好 $d$ 升,就让某个杯子里的 ...
- nyoj 21--三个水杯(隐式图bfs)
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识 ...
- 【UVA】658 - It's not a Bug, it's a Feature!(隐式图 + 位运算)
这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 < ...
- 八数码问题+路径寻找问题+bfs(隐式图的判重操作)
Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...
- uva658(最短路径+隐式图+状态压缩)
题目连接(vj):https://vjudge.net/problem/UVA-658 题意:补丁在修正 bug 时,有时也会引入新的 bug.假定有 n(n≤20)个潜在 bug 和 m(m≤100 ...
- UVA 658 状态压缩+隐式图+优先队列dijstla
不可多得的好题目啊,我看了别人题解才做出来的,这种题目一看就会做的实在是大神啊,而且我看别人博客都看了好久才明白...还是对状态压缩不是很熟练,理解几个位运算用了好久时间.有些题目自己看着别人的题解做 ...
- UVA - 658 It's not a Bug, it's a Feature! (隐式图的最短路,位运算)
隐式的图搜索,存不下边,所以只有枚举转移就行了,因为bug的存在状态可以用二进制表示,转移的时候判断合法可以用位运算优化, 二进制pre[i][0]表示可以出现的bug,那么u&pre[i][ ...
- UVa 10603 Fill (BFS && 经典模拟倒水 && 隐式图)
题意 : 有装满水的6升的杯子.空的3升杯子和1升杯子,3个杯子中都没有刻度.不使用道具情况下,是否可量出4升水呢? 你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第3个杯 ...
- Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)
1741. Communication Fiend Time limit: 1.0 second Memory limit: 64 MB Kolya has returned from a summe ...
随机推荐
- Leetcode题解(32)
107. Binary Tree Level Order Traversal II 题目 直接代码: /** * Definition for a binary tree node. * struct ...
- AngularJS学习篇(六)
AngularJS 控制器 AngularJS 应用程序被控制器控制. ng-controller 指令定义了应用程序控制器. 控制器是 JavaScript 对象,由标准的 JavaScript 对 ...
- ruby 正则表达式 匹配规则
- liunx 系统调用 getopt() 函数
命令行参数解析函数 -- getopt() getopt()函数声明如下: #include <unistd.h>int getopt(int argc, char * const arg ...
- 表空间与数据文件Offline,online的区别
首先明确,表空间与数据文件的关系:Oracle数据库表空间有两种,一种smallfile小文件表空间(默认),另一种bigfile大文件表空间: 默认表空间与数据文件的关系:允许一对多的处理方式,一个 ...
- Java钉钉开发_03_通讯录管理之 人员管理 和 部门管理
一.本节要点 1.通讯录权限 ISV(应用服务商)默认无管理通讯录的权限,企业应用默认有所有通讯录权限. 2.数据传输格式—JSON 请参见: Java_数据交换_fastJSON_01_用法入门 二 ...
- 基于IWICImage的截图代码
截图方式和以前一样, 用GetDC, 保存为JPG的方式改用IWICImage接口, 在我机器上 1920*1080 大概花费70毫秒左右, 比用TJPEGImage快了一倍多(TJPEGImage需 ...
- Mac上编译并运行Android5.0源码
下载.配置环境.build和运行参考的都是Android Source提供的文档,包括:Initializing a Build Environment,Downloading the Source和 ...
- matlab R2016a 中添加新的工具箱的方法
matlab添加新的工具箱分三步: 1. 下载新的工具箱,并解压. 2. 将解压后的工具箱文件夹移到安装的matlab中的toolbox文件夹中 3. 添加新文件夹及其子文件夹到路径中. 接下来以添加 ...
- Ubuntu Server无线上网
在自己电脑上装个Ubuntu Server,需要连接无线上网,参照附录的两个连接完成. 重置的自己路由器,只是为了找ssid和密码 配置步骤: 1. 生成无线上网密码配置文件 root@Ubuntu: ...