1. 程式人生 > >昂貴的聘禮 POJ - 1062(最短路)

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

在那 poj 方便 .... scanf using str per 但是

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


思路:我看網上的寫法是 酋長等級為Q ,則可行區間為 【Q-m,Q】 ...... 【Q,Q+m】,枚舉每個區間,然後不在區間內的點就不加入最短路,跑m遍最短路
我用了另一種寫法,總感覺有點搜索的意思,在優先隊列中存入的結構體中記錄當前路徑所走過的最高等級和最低等級,超過m就放棄這路徑,否則更新

技術分享圖片
 1 #include<cstdio>
 2
#include<cstring> 3 #include<queue> 4 using namespace std; 5 6 int m,n; 7 struct Node 8 { 9 int s; 10 int low,high; 11 int val; 12 Node(int s=0,int low=0,int high=0,int val=0):s(s),low(low),high(high),val(val){} 13 bool operator<(const Node x)const 14 { 15 return val > x.val; 16 } 17 }; 18 19 struct N 20 { 21 int y; 22 int next; 23 int val; 24 }node[10005]; 25 26 int cnt,head[105],level[105]; 27 void add(int x,int y,int val) 28 { 29 node[++cnt].y=y; 30 node[cnt].val =val; 31 node[cnt].next=head[x]; 32 head[x]=cnt; 33 } 34 35 priority_queue<Node>que; 36 int dist[105]; 37 bool vis[105]; 38 void dijstra() 39 { 40 while(!que.empty())que.pop(); 41 que.push(Node(0,level[1],level[1],0)); 42 memset(dist,0x3f,sizeof(dist)); 43 while(!que.empty()) 44 { 45 Node tmp = que.top(); 46 que.pop(); 47 if(vis[tmp.s])continue; 48 vis[tmp.s]=1; 49 dist[tmp.s] = tmp.val; 50 for(int i=head[tmp.s];i;i=node[i].next) 51 { 52 int to = node[i].y; 53 int low = min(tmp.low,level[to]); 54 int high = max(tmp.high,level[to]); 55 if(dist[to] > tmp.val + node[i].val && high - low <= m) 56 { 57 que.push(Node(to,low,high,tmp.val+node[i].val)); 58 } 59 } 60 61 } 62 } 63 64 int main() 65 { 66 scanf("%d%d",&m,&n); 67 for(int i=1;i<=n;i++) 68 { 69 int p,l,x; 70 scanf("%d%d%d",&p,&l,&x); 71 level[i] = l; 72 add(0,i,p); 73 for(int j=1;j<=x;j++) 74 { 75 int t,num; 76 scanf("%d%d",&t,&num); 77 add(t,i,num); 78 } 79 } 80 dijstra(); 81 printf("%d\n",dist[1]); 82 }
View Code

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