昂贵的聘礼 Dijkstra法
poj 1062
| Time Limit:?1000MS | ? | Memory Limit:?10000K |
| Total Submissions:?39437 | ? | Accepted:?11432 |
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
1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0Sample Output
5250對于從u點出發到w點的路徑中,他會跟很多等級的人交易,然而必須滿足在路徑中的點等級差不很超過一個M值,那么怎么對這樣的問題求解呢?我沒看報告前是很疑惑的!
假設如果給這條路徑加上一個附加條件的話,情況可能就有所變化了,要求最短路中的所有點的等級在一個區間內[a,b],如果能夠很好的給出這個區間的話,只要對圖中的點進行上篩選即可了。
這個區間的確定顯然不是隨便的,那么就要根據一定的條件了,從題意中我們知道,最后所有的最短路都會匯集在1號點,也就是說1號點是所有最短路都存在的點,好了,這個條件很重要,這樣我們就可以依照1號點來給定區間了,比如1號點等級為lev,那么也就是說在所有最短路的這些點都必須滿足在[lev-M,lev+M]這個區間里面。好了,可能你會迫不及待將這個區間作為最后的區間,在想想,如果在這個區間內出現的兩個點的他們之間的等級差超過了M值(這是存在的),顯然,不符合題意了,所以這個區間還有繼續縮小。其實只要稍微動動腦子,就可以找出這樣的區間[lev-M,lev],[lev-M+1,lev+1],... ...,[lev,lev+M],首先這些區間都滿足大區間的條件,而且如果將這些區間的某個作為篩選條件的話,在這個區間內的任意兩個點的等級都不會超過M值,這就是很特別的地方了(轉)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 const int INF=99999999; 5 int maps[105][105],v[105],d[105],N; 6 int l[105],p[105],in[105]; 7 8 int Dijkstra() 9 { 10 memset(v,0,sizeof(v)); 11 int i,j,k,mini; 12 13 for(i=1;i<=N;i++) 14 d[i]=INF; 15 d[1]=0; 16 for(i=1;i<=N;i++) 17 { 18 mini=INF;k=-1; 19 for(j=1;j<=N;j++) 20 { 21 if(!v[j] && in[j] && d[j]<mini) 22 mini=d[k=j]; 23 } 24 if(mini==INF) 25 break; 26 27 v[k]=1; 28 for(j=1;j<=N;j++) 29 { 30 if(!v[j] && in[j] && d[k]+maps[k][j]<d[j]) 31 { 32 d[j]=d[k]+maps[k][j]; 33 } 34 } 35 } 36 mini=INF; 37 for(i=1;i<=N;i++) 38 { 39 if(d[i]+p[i]<mini && v[i]) 40 mini=d[i]+p[i]; 41 } 42 return mini; 43 } 44 45 int main() 46 { 47 int m,x,T,V; 48 int i,j,minicost; 49 while(scanf("%d %d",&m,&N)!=EOF) 50 { 51 52 for(i=1;i<=N;i++) 53 { 54 for(j=1;j<=N;j++) 55 { 56 maps[i][j]=( i==j ? 0 :INF); 57 } 58 } 59 for(i=1;i<=N;i++) 60 { 61 scanf("%d %d %d",&p[i],&l[i],&x); 62 for(j=1;j<=x;j++) 63 { 64 scanf("%d %d",&T,&V); 65 if(maps[i][T]>V) 66 { 67 maps[i][T]=V; 68 } 69 } 70 } 71 int lev=l[1],coc; 72 minicost=INF; 73 for(i=0;i<=m;i++) 74 { 75 memset(in,0,sizeof(in)); 76 for(j=1;j<=N;j++) 77 { 78 if(l[1]-m+i<=l[j] && l[j]<=l[1]+i) 79 in[j]=1; 80 } 81 coc=Dijkstra(); 82 if(coc<minicost) 83 minicost=coc; 84 } 85 printf("%d\n",minicost); 86 } 87 return 0; 88 } View Code?
轉載于:https://www.cnblogs.com/cyd308/p/4474198.html
總結
以上是生活随笔為你收集整理的昂贵的聘礼 Dijkstra法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当INPUT 连续输入是连续触发
- 下一篇: 远程桌面管理