1. 程式人生 > >POJ 1062 昂貴的聘禮

POJ 1062 昂貴的聘禮

能夠 color 也看 系列 時也 class 表示 差距 out

題目:

年輕的探險家來到了一個印第安部落裏。在那裏他和酋長的女兒相愛了,於是便向酋長去求親。酋長要他用10000個金幣作為聘禮才答應把女兒嫁給他。探險家拿不出這麽多金幣,便請求酋長降低要求。酋長說:"嗯,如果你能夠替我弄到大祭司的皮襖,我可以只要8000金幣。如果你能夠弄來他的水晶球,那麽只要5000金幣就行了。"探險家就跑到大祭司那裏,向他要求皮襖或水晶球,大祭司要他用金幣來換,或者替他弄來其他的東西,他可以降低價格。探險家於是又跑到其他地方,其他人也提出了類似的要求,或者直接用金幣換,或者找到其他東西就可以降低價格。不過探險家沒必要用多樣東西去換一樣東西,因為不會得到更低的價格。探險家現在很需要你的幫忙,讓他用最少的金幣娶到自己的心上人。另外他要告訴你的是,在這個部落裏,等級觀念十分森嚴。地位差距超過一定限制的兩個人之間不會進行任何形式的直接接觸,包括交易。他是一個外來人,所以可以不受這些限制。但是如果他和某個地位較低的人進行了交易,地位較高的的人不會再和他交易,他們認為這樣等於是間接接觸,反過來也一樣。因此你需要在考慮所有的情況以後給他提供一個最好的方案。
為了方便起見,我們把所有的物品從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
題意描述:
輸入等級限制rl,和物品件數
輸入每件物品及其替代品
解題思路:

最短路問題,求花費的最少金幣,另外需要的是要所有交易的物品的等級不能超過等級限制。剛開始一位只要交易的前一位和後一位不超過等級限制就行了,WA了兩次,尷尬。
具體思路是枚舉每件物品的等級,當做最小等級,那麽在此前提下,所有等級超過它等級限制rl的和小於此件物品等級的都不能交易。遍歷所有物品等級,求出眾多最短路的
最少金幣即可。
代碼實現:
 1 #include<stdio.h>
 2 #include<string.h>
 3 struct N
 4 {
 5     int p,r;
 6 };
 7 struct N w[110];
 8 int rl,n,e[110][110
],book[110],dis[110]; 9 int Dijkstra(); 10 int inf=99999999; 11 int main() 12 { 13 int i,j,t,k,l,ans,temp; 14 while(scanf("%d%d",&rl,&n) != EOF) 15 { 16 for(i=1;i<=n;i++) 17 for(j=1;j<=n;j++) 18 e[i][j]=inf;//i==j時也初始化為inf 19 for(i=1;i<=n;i++) 20 { 21 scanf("%d%d%d",&w[i].p,&w[i].r,&t); 22 while(t--) 23 { 24 scanf("%d%d",&k,&l); 25 e[k][i]=l;//無向圖 26 } 27 } 28 29 ans=inf; 30 for(i=1;i<=n;i++) 31 { 32 int ml =w[i].r; 33 for(j = 1; j <= n; j ++) 34 { 35 if(w[j].r - ml > rl || ml > w[j].r) 36 book[j]=1; 37 else 38 book[j]=0; 39 } 40 temp = Dijkstra(); 41 if(ans > temp) 42 ans=temp;//邏輯關系 43 } 44 printf("%d\n",ans); 45 } 46 return 0; 47 } 48 int Dijkstra() 49 { 50 int i,j; 51 for(i=1;i<=n;i++) 52 dis[i]=w[i].p; 53 for(i=1;i<=n;i++) 54 { 55 int min = inf, k = -1; 56 for(j = 1; j <= n; j++) 57 { 58 if(!book[j] && dis[j] < min) 59 {//執行的是兩條語句,要加括號 60 min = dis[j]; 61 k = j; 62 } 63 } 64 book[k]=1; 65 for(j=1;j<=n;j++) 66 { 67 if(!book[j] && dis[j] > dis[k] + e[k][j]) 68 dis[j] = dis[k] + e[k][j]; 69 } 70 } 71 return dis[1]; 72 }

易錯分析:

1、初始化地圖時將i==j也初始化為無窮大,因為要求最少金幣。

2、分清是無向圖還是有向圖,此題為無向圖,因為交易是有方向的。

3、求最大或者最小時註意邏輯關系。

4、註意不要省括號,有時會更費時間去找錯。

POJ 1062 昂貴的聘禮