【解题报告】UVA10603 Fill BFS

最近做最短路专题训练,做了这道题。某秃子告诉我可以用优先队列优化一下,不过细想了一下似乎也没有优化太多。。

这道题的核心是把三个杯子的水量和当前已经倒得水量作为一个状态,从一个状态到下一个状态,用bfs寻找所有可能的状态。因为要求距离d最近的水量d',所以在判断的时候也要下一番功夫。当然了,剪枝是必要的。如果到达的这个状态用的水量比之前到达的时候用的多的话就不会进入队列。

PS:另外如果不使用greater而是重载小于号的话,一定要在函数名后面加上const。PPS:因为嫌麻烦重载了一下[]

#include <bits/stdc++.h>
using namespace std;
int v[201][201][201];
int ed;
struct node {
	int w[3], val;
	bool operator <(const node& x)const { return val < x.val; }
	int& operator [](const int&x) { return w[x]; }
};
int main()
{
	int T, mw[3], mn = 0x3f3f3f;
	cin >> T;
	int ans, wt;
	while (T--)
	{
		ans = 0x3f3f3f3f, wt = 0;
		memset(v, 0x3f, sizeof v);
		cin >> mw[0] >> mw[1] >> mw[2] >> ed;
		v[0][0][mw[2]] = 0;
		node x = { 0,0,mw[2],0 }, t;
		priority_queue<node>Q;
		Q.push(x);
		while (!Q.empty())
		{
			x = Q.top();
			Q.pop();
			for (int i = 0;i < 3;i++)//从杯子j往杯子i倒水
			{
				if (x[i] == ed)
				{
					if (wt < ed) { wt = ed;ans = x.val; }
					ans = min(ans, x.val);
					break;
				}
				if (wt <= x[i] && x[i] < ed)
				{
					if (!(x[i] == wt&&ans < x.val))
					{
						wt = x[i];ans = x.val;
					}
				}
				if (x[i] == mw[i])continue;//如果满了
				for (int j = 0;j < 3;j++)
				{
					if (i == j || x[j] == 0)continue;//如果空
					t = x;
					int p = min(t[j], mw[i] - t[i]);
					t.val += p;
					t[j] -= p;
					t[i] += p;
					if (v[t[0]][t[1]][t[2]] > t.val)
					{
						v[t[0]][t[1]][t[2]] = t.val;
						Q.push(t);
					}
				}
			}
		}
		if (ans == 0x3f3f3f3f) { ans = wt = 0; }
		cout << ans << ' ' << wt << endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值