高玩小q不僅喜歡玩尋寶遊戲,還喜歡一款公升級養成類遊戲。在這個遊戲的世界地圖中一共有n個城鎮,編號依次為1到n。
這些城鎮之間有m條單向道路,第i 條單項道路包含四個引數ui,vi,ai,bi,表示一條從ui號城鎮出發,在vi號城鎮結束的單向道路,因為是單向道路,這不意味著小q可以從vi沿著該道路走到ui。小q的初始等級level為1,每當試圖經過一條道路時,需要支付cost=log2level+ailevel點積分,並且經過該道路後,小q的等級會提公升ai級,到達level+ai級。但是每條道路都會在一定意義上歧視低消費玩家,準確地說,如果該次所需積分cost < bi,那麼小q不能經過該次道路,也不能提公升相應的等級。
注意:本遊戲中等級為正整數,但是積分可以是任意實數。
小q位於1號城鎮,等級為1,現在為了做任務要到n號城鎮去。這將會是一次奢侈的旅行,請寫乙個程式幫助小q找到需要支付的總積分最少的一條路線,或判斷這是不可能的。
input
第一行包含乙個正整數t(1≤t≤30),表示測試資料的組數。
每組資料第一行包含兩個整數n,m(2 ≤ n ≤ 100000,1 ≤ m ≤ 200000),表示城鎮數和道路數。
接下來m行,每行四個整數ui,vi,ai,bi(1≤ui,vi≤n,ui≠vi,0≤ai≤109,0≤bi≤60),分別表示每條單向道路。
output
對於每組資料,輸出一行乙個整數,即最少所需的總積分的整數部分,如:4.9999輸出4,1.0輸出1。若不存在合法路線請輸出−1。
sample input
1 3 3
1 2 3 2
2 3 1 6
1 3 5 0
sample output
2分析:首先這題肯定是個最短路沒的說,重點是如何處理,因為有level的存在,看似其使得邊權變成了動態的,對於一條邊,固定的唯有乙個ai值,還要對這個ai值做log2((leveli+a(i+1))/leveli)的處理才是真正的邊權。但其實可以通過化簡使題目多餘的限制去掉。
首先在當前點的等級設為level i ,在選擇邊時,有a[i+1]用於計算通過該邊的花費。
對於log2(n)對數,我們知道有,log2(x/y)=log2(x)-log2(y),因此,若當前從i- > j- > k
原式計算花費cost為 log2((level[i] +a[j])/level[i]) + log2((level[j] +a[k])/level[j])
轉換為減法後 log2(level[i]+a[j]) - log2(level[i]) + log2(level[j]+a[k]) - log2(level[j])
可以發現在行走過程中,level是如何變化的,是通過level[i]+a[j]得到了,也就是說,實際上level【i】+a【j】=level【j】。
在上式中通過等價替換,log2(level[i]+a[j])與- log2(level[j])因為相等被抵消掉了,剩餘 - log2(level[i]) + log2(level[j]+a[k]) 為i->k的花費
在看,我們從起點到到達終點的總花費是如何計算的,即σ(i=1~n) log2((level[i]+a[k])/leve[i]),其中,1~n指從起點出發到達終點的最短路徑,而不是1~n所有節點。a[k]表示當前結點出發,下一條邊的增加等級。轉換為求和式即:
原式= log2((level[1]+a[k1])/level[1]) + log2((level[2]+a[k2])/level[2]) + log2((level[3]+a[k3])/level[3]) + …………+log2((level[n-1]+a[kn-1])/level[n-1])
根據上面的化簡式,發現兩項之間的分子和分母可以抵消掉。化簡後得到:
-log2(level[1])+log2(level[n-1]+a[kn-1])
其中,題目已經說明,初始等級level為1級,那麼前面那項 -log2(level[1])即值為0。也就是說,最終結果即log2(level[n-1]+a[kn-1])這乙個式子。這個值拿去log2不談,level[n-1]+a[kn-1]這個值,不就是從起點開始到終點n前的乙個點的最小ai值之和嗎,之後機上了a[kn-1]即達到終點那條邊的最後乙個a值,簡單來說,即我們所要求的的最短路,其實和等級level毫無關係,全部被化簡掉了,整整要求的最短路的邊權,其實就是每條邊上增長的等級ai,也就是說,把ai放到圖上的邊權中,裸的求乙個最短路再對結果取log2即可。
題目中還有一種限制,要求花費cost小於邊上限制bi時,不需通過。我們已經把邊權轉換成了整數值,是不能再對其進行取log再與bi比較的,況且可能有精度損失。因此對於不等式 cost=log2((level+ai)/level ) < bi 對數逆運算,兩邊變為指數形式,即:
(level[i] +a[j])/level[i] < 2^(bi)去掉了前式的log,直接以整數形式對比兩值判斷是否能通過某條邊。
最後注意一下,最短路dijkstra的過程中若沒有用vis標記一下出佇列的節點會超時。。。這是之前沒做vis標記是從沒出現過的情況orz也算是給自己做的警示了。
ac**
hdu 2066 乙個人的旅行
我覺得這題應該用floyd演算法會更好一點吧,猜的,還沒學,囧.我是用dijstra暴力水過.嗯開始學floyd code include include include include include include include include include include include ...
Hdu 2066 乙個人的旅行
最短路問題 dijkstra 分析 1 本題的起始點和終點不唯一。假設有一點起始點離全部的相鄰城市的距離都是1,有一點終點離全部的想要去的目的地的距離也都是1,則將dijkstra出來的值減2即可。2 兩個城市之間的路不唯一,可有多條路,所以在輸入的時候做一下判斷,選取最小的。ac include ...
HDU2066 乙個人的旅行
problem description input 輸入資料有多組,每組的第一行是三個整數t,s和d,表示有t條路,和草兒家相鄰的城市的有s個,草兒想去的地方有d個 接著有t行,每行有三個整數a,b,time,表示a,b城市之間的車程是time小時 1 a,b 1000 a,b 之間可能有多條路 接...