在艾澤拉斯大陸上有一位名叫歪嘴哦的神奇術士,他是部落的中堅力量
有一天他醒來後發現自己居然到了聯盟的主城暴風城
在被眾多聯盟的士兵攻擊後,他決定逃回自己的家鄉奧格瑞瑪
在艾澤拉斯,有n個城市。編號為1,2,3,...,n。
城市之間有m條雙向的公路,連線著兩個城市,從某個城市到另乙個城市,會遭到聯盟的攻擊,進而損失一定的血量。
每次經過乙個城市,都會被收取一定的過路費(包括起點和終點)。路上並沒有收費站。
假設1為暴風城,n為奧格瑞瑪,而他的血量最多為b,出發時他的血量是滿的。
歪嘴哦不希望花很多錢,他想知道,在可以到達奧格瑞瑪的情況下,他所經過的所有城市中最多的一次收取的費用的最小值是多少。
這是一道二分答案
二分答案的本質就是列舉,在已知解範圍的情況下用二分的手段從解的範圍中尋找出解
題目:"他所經過的所有城市中最多的一次收取的費用的最小值是多少?"
這句話的意思實際上是指:
對於一條路徑 a , 定義函式f(a)。
對於路徑上的所有點權構成的集合s, 滿足f(a)=max(s)
而對於一張圖,從起點到終點存在多條路徑a1,a2,a3...
對於所有可能的路徑a1,a2,a3...,均存在對應的f(a1),f(a2),f(a3)...
求f(a1),f(a2),f(a3)...中的最小值
基本的思想就是二分,二分什麼呢?
被二分的一定是乙個包含解的集合
首先,你的f(a)是等於max(s)的,f(a)一定是乙個點權,即我們所求的解為乙個點權
而你走過的每乙個路徑中的最小點權f(a)一定在乙個區間內:即整張圖的最低點權與最高點權之間
通過對整張圖的點權進行排序,然後做二分,在整張圖的點權集合中找出乙個點權,這個點權是min( f(a1) f(a2) f(a3) ... ) 就是本題答案了
我們已經找到了解的集合:點權集合。
二分點權集合,每一次都會得到一手點權,這個點權將是路徑上所有點點權的天花板
在整張圖上尋找路徑,但是因為我們得到了乙個天花板,所以點權大於這個天花板的點就不能選
尋找路徑也應該是最短路,因為你會扣血,所以需要找到扣血最少的路徑
要是找到的這個路徑上的扣血總和依然致死,那麼我們找到的點權就是無效的,繼續向上二分,擴大點權範圍
要是不致死,那麼分出的點權就是有效的,繼續向下二分,縮小點權範圍
來自
#include#include#include#include#define n 10010
#define inf 0x3f3f3f3f
using namespace std;
struct edgee[100100];
int head[n],dis[n],vis[n],f[n],c[n],num_edge,n,m,b;
bool check(int x)
}} }
if(dis[n] < b) return 1;
return 0;
}inline void add(int u,int v,int w)
int main()
for(int i = 1,u,v,w;i <= m;++i)
sort(c + 1,c + 1 + n);
if(!check(inf))
int lb = 1,ub = n + 1,ans = 0;
while(lb + 1< ub)
else lb = mid;
} printf("%d\n",ans);
return 0;
}
解的範圍是整數,有兩種方式int lb = 1, ub = n+1;
while(lb + 1< ub)
int lb = 0, ub = n;
while(lb + 1< ub)
luogu P1462 通往奧格瑞瑪的道路
在艾澤拉斯大陸上有一位名叫歪嘴哦的神奇術士,他是部落的中堅力量 有一天他醒來後發現自己居然到了聯盟的主城暴風城 在被眾多聯盟的士兵攻擊後,他決定逃回自己的家鄉奧格瑞瑪 在艾澤拉斯,有n個城市。編號為1,2,3,n。城市之間有m條雙向的公路,連線著兩個城市,從某個城市到另乙個城市,會遭到聯盟的攻擊,進...
Luogu P1462 通往奧格瑞瑪的道路
暴風城 沒想到inf爆int卡了我乙個月.求收取費用最多的一次的最小值,顯然是要用二分答案。二分這個最大費用,每次用dijkstra求一下不經過收取費用大於二分值的城市的前提下的最短路,並判斷這個距離是否在血量範圍內。如下 include include include include includ...
洛谷1462 通往奧格瑞瑪的道路
洛谷1462 通往奧格瑞瑪的道路 題目背景 在艾澤拉斯大陸上有一位名叫歪嘴哦的神奇術士,他是部落的中堅力量 有一天他醒來後發現自己居然到了聯盟的主城暴風城 在被眾多聯盟的士兵攻擊後,他決定逃回自己的家鄉奧格瑞瑪 題目描述 在艾澤拉斯,有n個城市。編號為1,2,3,n。城市之間有m條雙向的公路,連線著...