poj2106,POJ-1062-昂貴的聘禮 (最短路)

 2023-10-06 阅读 27 评论 0

摘要:????????????????????????????????????????????????????????? 昂貴的聘禮 ? Description 年輕的探險家來到了一個印第安部落里。在那里他和酋長的女兒相愛了,于是便向酋長去求親。酋長要他用10000個金幣作為聘禮才答應把女兒嫁給他。探險家拿不出這么多金幣,便請

????????????????????????????????????????????????????????? 昂貴的聘禮
?

Description

年輕的探險家來到了一個印第安部落里。在那里他和酋長的女兒相愛了,于是便向酋長去求親。酋長要他用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

poj2106。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

解題思路

每個物品看成一個節點,酋長的允諾也看作一個物品, 如果一個物品加上金幣可以交換另一個物品,則這兩個節點之間有邊,權值為金幣數,求第一個節點到所有節點的最短路。因為有等級限制,所以枚舉每個點作為最低等級,選取符合所有符合等級限制的點

程序代碼

#include<stdio.h>
#include<string.h>
void dijstra(int st,int et);
#define inf 99999999
int m,n;
int p[110],l[110],x,t,v;
int e[110][110],book[110],dis[110];
int main()
{int i,j,min;while(scanf("%d%d",&m,&n)!=EOF){for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(i==j)e[i][j]=0;elsee[i][j]=inf;for(i=1;i<=n;i++){scanf("%d%d%d",&p[i],&l[i],&x);for(j=1;j<=x;j++){scanf("%d%d",&t,&v);e[i][t]=v;}}min=inf;for(i=l[1]-m;i<=l[1];i++){memset(book,0,sizeof(book));dijstra(i,i+m);for(j=1;j<=n;j++)if(min>dis[j]+p[j])min=dis[j]+p[j];}printf("%d\n",min);}return 0;
}
void dijstra(int st,int et)
{int i,j,k,u,min;for(i=2;i<=n;i++){dis[i]=e[1][i];if(l[i]<st||l[i]>et){book[i]=1;dis[i]=inf;}}dis[1]=0;book[1]=1;for(k=1;k<=n-1;k++){min=inf;for(i=1;i<=n;i++)if(book[i]==0&&dis[i]<min){min=dis[i];u=i;}if(min==inf)break;//如果沒有可以去的點了就直接跳出 book[u]=1;for(i=1;i<=n;i++)if(book[i]==0&&dis[i]>dis[u]+e[u][i])dis[i]=dis[u]+e[u][i];}
}

?

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/122974.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息