dijkstra+二分答案【洛谷P1462】
阿新 • • 發佈:2018-11-21
傳送門:https://www.luogu.org/problemnew/show/P1462
第一次做了這種求最短路而且要二分答案的。
比較困難吧,但是做了以後也基本領會了其中的道理。
首先二分答案開始寫炸了,
這裡放上一個模板吧!:
int ans = 0;
while(l<=r)
{
int mid = (l+r)/2;
if(dijkstra(mid))
{
ans = mid;
r = mid-1;
}
else
{
l = mid+1;
}
}
cout<<ans<<endl;
這樣子的二分答案應該是可以的吧!
然後這個題目直接二分金錢就可以了。
每一次判斷加邊的時候判斷一下該邊的金額,小於等於mid就可以。
挺簡單的啊!
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5+7; const int INF = 1e9+7; int d[maxn]; int f[maxn]; int n,m,b; struct node { int now; ll cost; bool operator<(const node &a)const { return cost>a.cost; } }; struct edge { int to; ll cost; }; vector<edge> G[maxn]; bool dijkstra(int x) { fill(d,d+maxn,INF); priority_queue<node> q; d[1] = 0; q.push((node){1,d[1]}); while(!q.empty()) { node tmp = q.top(); q.pop(); if(d[tmp.now]<tmp.cost) continue; for(int i=0;i<G[tmp.now].size();i++) { int v = G[tmp.now][i].to; if(d[v]>d[tmp.now]+G[tmp.now][i].cost && f[v]<=x) { d[v] = d[tmp.now]+G[tmp.now][i].cost; q.push((node){v,d[v]}); } } } return d[n]<=b; } void init() { fill(d,d+maxn,INF); } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m>>b; init(); int l = INF; int r = -INF; for(int i=1;i<=n;i++) { cin>>f[i]; l = min(l,f[i]); r = max(r,f[i]); } for(int i=0;i<m;i++) { int x,y,z; cin>>x>>y>>z; if(x==y) continue; G[x].push_back((edge){y,z}); G[y].push_back((edge){x,z}); } if(!dijkstra(INF+1)) { cout<<"AFK"<<endl; return 0; } int ans = 0; while(l<=r) { int mid = (l+r)/2; if(dijkstra(mid)) { ans = mid; r = mid-1; } else { l = mid+1; } } cout<<ans<<endl; return 0; }