年輕的探險家來到了乙個印第安部落裡。在那裡他和酋長的女兒相愛了,於是便向酋長去求親。酋長要他用10000個金幣作為聘禮才答應把女兒嫁給他。探險家拿不出這麼多金幣,便請求酋長降低要求。酋長說:"嗯,如果你能夠替我弄到大祭司的皮襖,我可以只要8000金幣。如果你能夠弄來他的水晶球,那麼只要5000金幣就行了。"探險家就跑到大祭司那裡,向他要求皮襖或水晶球,大祭司要他用金幣來換,或者替他弄來其他的東西,他可以降低**。探險家於是又跑到其他地方,其他人也提出了類似的要求,或者直接用金幣換,或者找到其他東西就可以降低**。不過探險家沒必要用多樣東西去換一樣東西,因為不會得到更低的**。探險家現在很需要你的幫忙,讓他用最少的金幣娶到自己的心上人。另外他要告訴你的是,在這個部落裡,等級觀念十分森嚴。地位差距超過一定限制的兩個人之間不會進行任何形式的直接接觸,包括交易。他是乙個外來人,所以可以不受這些限制。但是如果他和某個地位較低的人進行了交易,地位較高的的人不會再和他交易,他們認為這樣等於是間接接觸,反過來也一樣。因此你需要在考慮所有的情況以後給他提供乙個最好的方案。
為了方便起見,我們把所有的物品從1開始進行編號,酋長的允諾也看作乙個物品,並且編號總是1。每個物品都有對應的**p,主人的地位等級l,以及一系列的替代品ti和該替代品所對應的"優惠"vi。如果兩人地位等級差距超過了m,就不能"間接交易"。你必須根據這些資料來計算出探險家最少需要多少金幣才能娶到酋長的女兒。
輸入第一行是兩個整數m,n(1 <= n <= 100),依次表示地位等級差距限制和物品的總數。接下來按照編號從小到大依次給出了n個物品的描述。每個物品的描述開頭是三個非負整數p、l、x(x < n),依次表示該物品的**、主人的地位等級和替代品總數。接下來x行每行包括兩個整數t和v,分別表示替代品的編號和"***格"。
輸出最少需要的金幣數。
1 4525010000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
輸出最小的金幣數,這道題首先想到的就是建圖跑最小路,我最開始用的方法是根據所給資訊把邊權和點權都加上,然後在跑dij的時候判斷
如果選擇邊權,那麼還要加和這個點的兒子的權,如果選擇點權就不用,然後統計到各個點最小距離。
打了一下樣例沒過,然後回去想,發現加的是雙向邊,於是又加了乙個vis陣列判斷是否訪問過,這次樣例過了,交上去wa
再仔細想一下,先不管我的點權和邊權處理有沒有問題,就乙個問題是很難解決的,就是終點是什麼,不一定所有的點都能當做本次統計的終點
也就是說它會直接返回最小值,不管這個最小值是不是已經把所有需要的點權邊權都包括進去了,比如我要買二號物品來降低一號物品**,在統計
到二號物品的路程時,直接返回了邊權,但點權也是應該加上的,所以沒有選完全 我感覺還是我的程式有問題
重新思考,有沒有一種方法能夠讓程式自動判斷選擇邊權還是點權,並且終點是一樣的?
受如果使用該物品的話邊權和點權必選其一的啟發,我們可以採用超級源點,即把所有的點的點權作為這個點和超級源點的邊權,於是又跑一遍
又沒過樣例,這次我發現乙個問題,我加的是雙向邊,而加雙向邊是肯定不行的,因為邊權表示買二號物品得到三號物品的優惠,如果加雙向的話就
表明買三號物品也能得到二號物品的優惠,這顯然是不對的,於是我們考慮邊的方向,從源點出來,邊的去向一定是指向每個點,因為我們是以源點
為起點,一號物品為終點跑的dij,所以輸入時,如果買a對b有優惠,那麼add_edge(a->b),這樣就可以保證終點是一樣的,且最短路徑上每個點的
點權或邊權都被選完全了。
修改完**,測了測樣例,對了!然後交上去,wa。。。。
接著我思考半天後找到了我最開始過深考慮的問題——等級,我起初是怎麼處理的呢?我在建圖時判斷,如果乙個點的等級與第一物品的差值的
絕對值小於m,就不加這個點及其周圍的邊。這麼看好像是對的,舉個例子,m=3,level[1]=8,我們買了level[2]=6,level[3]=10的兩個物品,由題意,
這不被允許,所以不能這麼判斷,但這給了我乙個啟發:買的物品價值範圍(levelmax-levelmin<=m),所以我們可以考慮列舉物品的價值範圍,每次
對於列舉的範圍進行dij求最短路,輸出最短的路徑即可。
#include#includecode#include
#include
using
namespace
std;
const
int n=110,inf=0x3f3f3f3f
;struct
edgee[n*n];
struct
node;
node(
int a,int b)
bool
operator
< (const node&a)const
};int
head[n],len,lev[n],ans,m,n,dis[n];
void ins(int a,int b,int
c)void dij(int
level)
} }ans=min(ans,dis[1
]);}
intmain() }
for(int i=lev[1]-m;i<=lev[1];i++)
dij(i);
printf(
"%d\n
",ans);
}
這個問題看起來還是比較難的,但是想明白以後也比較簡單,下次在做題的時候一定把問題先想清楚,邊做邊想太難了。。。。。。
昂貴的聘禮 poj 1062 最短路
沒看好題目條件 隨便寫了個弗洛伊德就交了 實際上兩個身份差距大的人是連間接交易都不允許的 所以列舉每個等級區間並對其用dijkstra演算法找最小值 ac include include include include include include include include include ...
POJ 1062 昂貴的聘禮 最短路
假設乙個起點0,根據題目給出的權值構圖,答案就是從0到1之間的最短路。這裡要注意的是這個等級限制的問題。首先等級限制不是相鄰點之間的限制,而是整體路徑的。等級的限制可以通過假設乙個點為最低點求最短路,我假設某個點是最短路中等級最低的,然後求最短路。每列舉乙個點就求一次最短路,取最小的值。因為你列舉的...
poj 1062昂貴的聘禮(最短路)
題目 昂貴的聘禮 time limit 1000ms memory limit 10000k total submissions 61174 accepted 18489 description 年輕的探險家來到了乙個印第安部落裡。在那裡他和酋長的女兒相愛了,於是便向酋長去求親。酋長要他用10000...