POJ 1062 解题报告

来源:互联网 发布:js 位运算符 编辑:程序博客网 时间:2024/06/03 03:12

这道题实际上是单源最短路径问题,每条边(从一个物品到替换它的物品之间)都有一个权值,即cost。问题是求从第一个物品到其他所有物品的最低开销,这个开销除了路径总cost外还得包含这个物品的价值(因为这个物品是最终替代第一个物品的物品)。

明白了上述这些后,自然而然的想法就是应用最短路径算法,比如Dijkstra,SPFA或是Bellman-Ford。

这个问题的有意思的地方在于它还对可选的物品有个限制,即从第一个物品到每个物品的路径上的物品的Level之差必须在M以内。一个简单的处理方法就是做枚举。假设第一个物品的Level是L(准确的说是拿物品的人的Level,而第一个物品是必须“交易”的,无论选第一个物品还是选它的替代品)。那么Level的最低值low范围为[L - M, L]。相应的Level最高值high为low + M。所以需要对low,high的限定范围做个枚举,跑这个多次单源最短路径,然后求出所有这些中的最小开销。

事实证明Dijkstra是个非常高效的方法,即使在实现得很烂的情况下(如本题的实现没有用priority_queue,所以每步选min的时间都是O(N))。时间仍然是0ms。

可以参见http://poj.org/showmessage?message_id=183977。代码实现得很清楚。

1062Accepted168K0MSC++3031B

/* ID: thestor1 LANG: C++ TASK: poj1062 */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <limits>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;class Substitute{public:int T, V;Substitute() {}Substitute(int T, int V) : T(T), V(V) {}};class Item{public:int P, L, minP;vector<Substitute> substitutes;Item() : minP(-1) {}Item(int P, int L) : P(P), L(L), minP(-1) {}};int dfs(vector<Item> &items, int t, int low, int high, const int M){if (items[t].minP >= 0){return items[t].minP;}int minP = items[t].P;for (int i = 0; i < items[t].substitutes.size(); ++i){if (low <= items[items[t].substitutes[i].T].L && items[items[t].substitutes[i].T].L <= high){// substitutes[i].T, substitutes[i].Vint price = dfs(items, items[t].substitutes[i].T, max(low, items[items[t].substitutes[i].T].L - M), min(high, items[items[t].substitutes[i].T].L + M), M);if (price + items[t].substitutes[i].V < minP){minP = price + items[t].substitutes[i].V;}}}items[t].minP = minP;return minP;}int dijkstra(vector<Item> &items, const int low, const int high, vector<bool> &visited, vector<int> &dis){int N = items.size();for (int i = 0; i < N; ++i){if (items[i].L < low || items[i].L > high){visited[i] = true;}else{visited[i] = false;}dis[i] = INT_MAX;}dis[0] = 0;for (int i = 0; i < N; ++i){int mindis = INT_MAX, minu = -1;for (int j = 0; j < N; ++j){if (!visited[j] && dis[j] < mindis){mindis = dis[j];minu = j;}}if (mindis == INT_MAX){break;}visited[minu] = true;for (int j = 0; j < items[minu].substitutes.size(); ++j){Substitute substitute = items[minu].substitutes[j];if (!visited[substitute.T] && mindis < INT_MAX - substitute.V && mindis + substitute.V < dis[substitute.T]){dis[substitute.T] = mindis + substitute.V;}}}int minP = INT_MAX;for (int i = 0; i < N; ++i){if (dis[i] < INT_MAX - items[i].P && dis[i] + items[i].P < minP){minP = dis[i] + items[i].P;}}return minP;}int main(){int M, N;scanf("%d%d", &M, &N);vector<Item> items(N);int X, T, V;for (int i = 0; i < N; ++i){scanf("%d%d%d", &items[i].P, &items[i].L, &X);for (int j = 0; j < X; ++j){scanf("%d%d", &T, &V);T--;items[i].substitutes.push_back(Substitute(T, V));}}int minP = INT_MAX;vector<bool> visited(N);vector<int> dis(N);for (int low = items[0].L - M; low <= items[0].L; ++low){int high = low + M;int price = dijkstra(items, low, high, visited, dis);if (price < minP){minP = price;}}printf("%d\n", minP);return 0;  }





0 0
原创粉丝点击