例题7-8 倒水问题(Fill, UVa 10603)

来源:互联网 发布:开淘宝店需要电脑吗 编辑:程序博客网 时间:2024/06/04 19:17
1. 粗略估计状态数不超过40401,枚举所有状态,来搜索最接近的d。
2. 本题的目标是倒水量最少,定义从状态s到状态v的边权为vol,类似dijkstra做法。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <sstream>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define maxn 205#define maxm 15#define mod 1000000007#define INF 1000000007#define eps 1e-5#define PI 3.1415926535898using namespace std;//-------------------------CHC------------------------------//struct Node {int v[3], d;bool operator<(const Node &r) const {return d > r.d;}};int cap[3], ans[maxn];bool vis[maxn][maxn];void solve(int a, int b, int c, int d) {cap[0] = a, cap[1] = b, cap[2] = c;CLEAR(ans, -1);CLEAR(vis, 0);priority_queue<Node> q;Node s;s.v[0] = s.v[1] = 0, s.v[2] = c, s.d = 0;q.push(s);vis[0][0] = true;while (q.size()) {Node u = q.top(); q.pop();for (int i = 0; i < 3; ++i)if (ans[u.v[i]] == -1 || u.d < ans[u.v[i]])ans[u.v[i]] = u.d;if (ans[d] >= 0) break;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 vol = min(cap[j], u.v[i] + u.v[j]) - u.v[j];Node v;memcpy(&v, &u, sizeof(u));v.d = u.d + vol;v.v[i] -= vol;v.v[j] += vol;if (!vis[v.v[0]][v.v[1]])vis[v.v[0]][v.v[1]] = true, q.push(v);}}while (d >= 0) {if (ans[d] >= 0) {printf("%d %d\n", ans[d], d);return;}--d;}}int main() {int t;cin >> t;while (t--) {int a, b, c, d;cin >> a >> b >> c >> d;solve(a, b, c, d);}return 0;}

原创粉丝点击