零食店
snackstore.in snackstore.out
時間限制:1 s 內存限制:256 MB
【題目描述】
成功找到了學長之后學姐感覺到有些餓,于是決定去附近的零食店給自己和學長買些零食。
焦作市的有n家零食店,由m條道路連接著這些零食店,每條道路都有自己的長度l,每家零食店都有自己的消費指數。
由于學姐是個窮B,所以去買零食的路上不能經過某些消費指數超過一定限度的店。
同時由于學姐體力有限,所以去買零食的過程中走的路程不能太長。
想來想去學姐決定去問學長買什么零食比較好,反正到最后都是學長吃╮(╯_╰)╭
在去問之前,學姐準備先做好準備,她把焦作市(所有零食店)的地圖給了你,希望你能編出一個程序快速回答她從某個零食店出發,在上述限制下有多少家零食店可供她挑選。
【輸入格式】
第一行三個正整數n,m,q,分別代表零食店數,道路數和詢問數。
接下來一行n個正整數,第i個正整數vi代表第i家零食店的消費指數。
接下來m行,第i行三個正整數x,y,l,代表第i條道路連接編號為x和y的兩個零食店,長度為l。
接下來q行第i行三個正整數s,c,d,代表第i個詢問要求從s出發,所經過的零食店的消費指數不能超過c(除了起點和終點以外),且行走路程不超過d。
【輸出格式】
一共q行,第i行一個整數代表在第i個詢問的要求下有多少家零食店可供學姐挑選。
【樣例輸入】
5 5 2
1 2 3 4 5
1 2 1
1 3 4
2 3 2
1 4 3
2 5 1
1 1 3
2 1 2
【樣例輸出】
2
3
【提示】
樣例中第一個詢問能去編號為2/4的零食店。
第二個詢問能去編號為1/3/5的零食店。
對于40%的數據,n≤10,m≤20,q=1。
對于70%的數據,m≤500,q≤10000。
對于100%的
數據,n≤100,m≤10000,q≤1000000,vi,c,d≤10^9,1≤x,y,s≤n,l≤10^6。
100
這道題應該讓我對最短路的理解更深了,基本想法和標解一樣,但很可惜
最短路寫不出來233
70%的數據量點數邊數和詢問數都比較小,每次詢問時去掉不符合條件的點(但仍要計算出這些點的dis值,只是不用這些點進行三角形迭代)后使用任意單源最短路算法解決即可。
消費指數的限制對應只能經過消費指數排名前幾的點,而路徑長度的限制對應只能抵達最短路排名前幾的點,所以我們考慮能不能預處理出g[k][i][j]代表從i出發只經過消費指數前k的點,距離i第j短的點距離為多少,這樣的話每次詢問只需要二分出k,然后在g[k][i]數組中二分就可以了。
預處理時我們可以當做動態加點的全源最短路,我們用動態規劃的轉移方程表示這個過程:用f[k][i][j]代表i出發只經過消費指數前k的點,i到j的最短路為多少。
f[k][i][j]=min{f[k-1][i][j],f[k-1][i][v[k]]+f[k-1][v[k]][j]}(其中v[k]代表消費指數排第k的點,1≤i,j≤n)
而f[0]數組很顯然就是這個圖的鄰接矩陣。
求出f數組之后將所有f[k][i]數組排序就是上面所求的g數組了,詢問的時候加兩個二分即可,時間復雜度為O(n^3logn+qlognn),沒有可以去卡不排序每次詢問在f數組中枚舉的算法,但是泥萌要知道這個做法有優化的空間。
聰明的小朋友們已經看出來了上面這個動態規劃就是floyd算法。
有很多算法都是實現簡單但是想要深入理解起來并不簡單的,比如floyd/FFT/FWT/后綴自動機等,希望大家在學算法的時候要理解得透徹一些,不要再碰到模板題還不會寫了。
梁哥的做法,我覺得更好,k在Floyd中的作用是松弛,那么可以對查詢按照c排序,每次取不大于c的k接著上一次的dis繼續做,這樣的結果其實就是一邊Floyd。
總結
- 上一篇: 5大过程组与整体管理
- 下一篇: 冲突处理