POJ 1062 昂貴的聘禮 (最短路應用 Dijkstra演算法)
昂貴的聘禮
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 41464 | Accepted: 12103 |
Description
年輕的探險家來到了一個印第安部落裡。在那裡他和酋長的女兒相愛了,於是便向酋長去求親。酋長要他用10000個金幣作為聘禮才答應把女兒嫁給他。探險家拿不出這麼多金幣,便請求酋長降低要求。酋長說:"嗯,如果你能夠替我弄到大祭司的皮襖,我可以只要8000金幣。如果你能夠弄來他的水晶球,那麼只要5000金幣就行了。"探險家就跑到大祭司那裡,向他要求皮襖或水晶球,大祭司要他用金幣來換,或者替他弄來其他的東西,他可以降低價格。探險家於是又跑到其他地方,其他人也提出了類似的要求,或者直接用金幣換,或者找到其他東西就可以降低價格。不過探險家沒必要用多樣東西去換一樣東西,因為不會得到更低的價格。探險家現在很需要你的幫忙,讓他用最少的金幣娶到自己的心上人。另外他要告訴你的是,在這個部落裡,等級觀念十分森嚴。地位差距超過一定限制的兩個人之間不會進行任何形式的直接接觸,包括交易。他是一個外來人,所以可以不受這些限制。但是如果他和某個地位較低的人進行了交易,地位較高的的人不會再和他交易,他們認為這樣等於是間接接觸,反過來也一樣。因此你需要在考慮所有的情況以後給他提供一個最好的方案。
為了方便起見,我們把所有的物品從1開始進行編號,酋長的允諾也看作一個物品,並且編號總是1。每個物品都有對應的價格P,主人的地位等級L,以及一系列的替代品Ti和該替代品所對應的"優惠"Vi。如果兩人地位等級差距超過了M,就不能"間接交易"。你必須根據這些資料來計算出探險家最少需要多少金幣才能娶到酋長的女兒。
為了方便起見,我們把所有的物品從1開始進行編號,酋長的允諾也看作一個物品,並且編號總是1。每個物品都有對應的價格P,主人的地位等級L,以及一系列的替代品Ti和該替代品所對應的"優惠"Vi。如果兩人地位等級差距超過了M,就不能"間接交易"。你必須根據這些資料來計算出探險家最少需要多少金幣才能娶到酋長的女兒。
Input
輸入第一行是兩個整數M,N(1 <= N <= 100),依次表示地位等級差距限制和物品的總數。接下來按照編號從小到大依次給出了N個物品的描述。每個物品的描述開頭是三個非負整數P、L、X(X < N),依次表示該物品的價格、主人的地位等級和替代品總數。接下來X行每行包括兩個整數T和V,分別表示替代品的編號和"優惠價格"。
Output
輸出最少需要的金幣數。
Sample Input
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
Sample Output
5250
題目連結:http://poj.org/problem?id=1062
題目分析:很經典的一道題,把探險家當作第0個點,按要求建立有向圖,因為要求交易集合裡的所有人的等級差距不能大於m,因此最後的答案的等級差距範圍必然在lev[1] - m到lev[1] + m,之間,列舉當前最大最小等級做Dijkstra,取最小即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int const MAX = 500;
int const INF = 0x3fffffff;
int m, n;
int dis[MAX], mp[MAX][MAX];
int lev[MAX];
bool vis[MAX];
int Dijkstra(int v0, int l, int r)
{
for(int i = 0; i <= n; i++)
dis[i] = INF;
for(int i = 0; i <= n; i++)
dis[i] = mp[v0][i];
dis[v0] = 0;
vis[v0] = true;
for(int i = 0; i < n; i++)
{
int u, mi = INF;
for(int j = 0; j <= n; j++)
{
if(!vis[j] && dis[j] < mi)
{
mi = dis[j];
u = j;
}
}
vis[u] = true;
for(int j = 0; j <= n; j++)
if(lev[j] <= r && lev[j] >= l && lev[u] <= r && lev[u] >= l)
if(!vis[j] && dis[j] > dis[u] + mp[u][j])
dis[j] = dis[u] + mp[u][j];
}
return dis[1];
}
int main()
{
while(scanf("%d %d", &m, &n) != EOF)
{
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= n; j++)
{
mp[i][j] = INF;
if(i == j)
mp[i][j] = 0;
}
}
for(int i = 1; i <= n; i++)
{
int x;
scanf("%d %d %d", &mp[0][i], &lev[i], &x);
for(int j = 0; j < x; j++)
{
int t, v;
scanf("%d %d", &t, &v);
mp[t][i] = v;
}
}
int ans = INF;
for(int i = lev[1] - m; i <= lev[1]; i++)
{
memset(vis, false, sizeof(vis));
ans = min(ans, Dijkstra(0, i, i + m));
}
printf("%d\n", ans);
}
}
相關文章
- POJ 1062-昂貴的聘禮(最短路-預處理限制點)
- 「日常訓練」「小專題·圖論」 昂貴的聘禮(1-4)圖論
- POJ2387 Til the Cows Come Home【最短路 Dijkstra演算法】演算法
- 最短路dijkstra演算法演算法
- 最短路 - Dijkstra 演算法演算法
- 計算機史上最昂貴的域名Top 10計算機
- 最短路徑之Dijkstra演算法演算法
- 最短路演算法之:Dijkstra 演算法演算法
- 程式碼歷史上最昂貴的 7 個錯誤
- 最短路徑問題 (dijkstra演算法)演算法
- 單源最短路徑-Dijkstra演算法演算法
- 單源最短路徑 -- Dijkstra演算法演算法
- dijkstra最短路演算法模板(雙源)演算法
- 最短路-樸素版Dijkstra演算法&堆優化版的Dijkstra演算法優化
- TheNextWeb:史上售價最昂貴的15個域名Web
- 100個替代昂貴商業軟體的開源應用
- 一個人的旅行 (dijkstra演算法求最短路)演算法
- 圖的單源最短路徑(Dijkstra演算法)演算法
- 最短路徑——Dijkstra演算法和Floyd演算法演算法
- 最短路徑—Dijkstra演算法和Floyd演算法演算法
- 10行實現最短路演算法——Dijkstra演算法
- 最短路演算法詳解(Dijkstra/SPFA/Floyd)演算法
- 最短路之Dijkstra
- 圖論-Dijkstra最短路圖論
- 2020國人彩禮地圖:哪個省的彩禮最貴?地圖
- 最短路徑——dijkstra演算法程式碼(c語言)演算法C語言
- 最短路徑—Dijkstra(迪傑斯特拉)演算法演算法
- 0016:單源最短路徑(dijkstra演算法)演算法
- 如何在 Java 中實現 Dijkstra 最短路演算法Java演算法
- 求兩點之間最短路徑-Dijkstra演算法演算法
- 卡達世界盃上最昂貴的TOP10球隊——你猜對了嗎?
- HDU3790 最短路徑問題【Dijkstra演算法】演算法
- 單源最短路徑複習--Dijkstra演算法和Floyd演算法演算法
- POJ 1511 Invitation Cards(最短路spfa演算法)演算法
- 一篇文章講透Dijkstra最短路徑演算法演算法
- python實現Dijkstra演算法之 最短路徑問題Python演算法
- 《圖論》——最短路徑 Dijkstra演算法(戴克斯特拉演算法)圖論演算法
- 資料結構與演算法——最短路徑Dijkstra演算法的C++實現資料結構演算法C++