#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int INF = 1<<29;
const int maxn = 100 + 10;
struct Node {
int p, l, x;
}node[maxn];
struct PNode {
int d, u;
PNode(int d, int u) : d(d), u(u) {}
PNode(){}
bool operator < (const PNode & rhs) const {
return d > rhs.d;
}
};
vector<int>E[maxn], W[maxn]; // E保存連接的物品 W保存優惠後的花費
int n, m, d[maxn];
bool vis[maxn];
int res;
int Dijkstra(int L, int R) {
for( int i=1; i<=n; i++ ) d[i] = INF;
d[1] = node[1].p;
priority_queue<PNode>q; // 優先隊列優化
q.push(PNode(node[1].p, 1));
while(!q.empty()) {
PNode f = q.top(); q.pop();
//printf("ff = %d\n", f.u);
for( int i=0; i<E[f.u].size(); i++ ) {
int v = E[f.u][i];
if(node[v].l >= L && node[v].l <= R) {
if(d[v] > d[f.u] + node[v].p - (node[f.u].p-W[f.u][i])) {
d[v] = d[f.u] + node[v].p - (node[f.u].p-W[f.u][i]);
res = min(d[v], res); // res爲最終結果
PNode tmp;
tmp.d = d[v];
tmp.u = v;
q.push(tmp);
}
}
}
}
return res;
}
int main() {
freopen("in", "r", stdin);
while(scanf("%d%d", &m, &n) != EOF) {
for( int i=1; i<=n; i++ ) E[i].clear(), W[i].clear();
for( int i=1; i<=n; i++ ) {
scanf("%d%d%d", &node[i].p, &node[i].l, &node[i].x);
for( int j=0; j<node[i].x; j++ ) {
int a, b;
scanf("%d%d", &a, &b);
E[i].push_back(a);
W[i].push_back(b);
}
}
res = node[1].p;
for( int i=node[1].l-m; i<=node[1].l; i++ ) { // 枚舉交易中出現的地位的區間
Dijkstra(i, i+m);
}
printf("%d\n", res);
}
return 0;
}
POJ 1062 昂貴的聘禮 (Dijkstra算法的運用)
題目類型 Dijkstra算法的運用
題目意思
中文題目描述
解題方法
先枚舉地位的範圍(因爲第1件物品必須在交易中出現所以範圍區間的左端點就是 L1-m -> L1 右端點範圍是 L1 -> L1+m)
確定範圍後就是類似Dijkstra算法的貪心過程
d[i] 表示交易終點停在第 i 個物品時總共所需的花費 那麼每次取最小的 d[i] 去更新其他的 d[] 即可
參考代碼 - 有疑問的地方在下方留言 看到會盡快回復的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.