Luogu P1462 通往奥格瑞玛的道路
没想到INF爆int卡了我一个月...
求收取费用最多的一次的最小值,显然是要用二分答案。
二分这个最大费用,每次用dijkstra求一下不经过收取费用大于二分值的城市的前提下的最短路,
并判断这个距离是否在血量范围内。
代码如下
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<queue> #define MogeKo qwq using namespace std; const int maxn = 1e6+10; const int INF = 0x3f3f3f3f; int n,m,HP; int x,y,z,cnt,ans; int head[maxn],to[maxn],nxt[maxn],val[maxn]; int dis[maxn],c[maxn]; bool vis[maxn]; void add(int x,int y,int z) { to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt; val[cnt] = z; } void dijkstra(int top) { priority_queue < pair<int,int> , vector< pair<int,int> > ,greater< pair<int,int> > > q; dis[1] = 0; q.push(make_pair(0,1)); while(!q.empty()) { int u = q.top().second; q.pop(); if(vis[u])continue; vis[u] = 1; for(int i = head[u]; i; i = nxt[i]) { int v = to[i]; if(dis[u] + val[i] < dis[v] && c[v] <= top) { dis[v] = dis[u] + val[i]; q.push(make_pair(dis[v],v)); } } } } void init(){ memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) dis[i] = INF; } int BS() { int ret; long long l = max(c[1],c[n]),r = INF; while(l < r){ long long mid = (l+r)>>1; init(); dijkstra((int)mid); if(dis[n] < HP){ ret = mid; r = mid; } else l = mid+1; } init(); dijkstra(ret); if(dis[n] >= HP) ret = -1; return ret; } int main() { scanf("%d%d%d",&n,&m,&HP); for(int i = 1;i <= n;i++) scanf("%d",&c[i]); for(int i = 1;i <= m;i++){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } ans = BS(); if(ans!=-1)printf("%d",ans); else printf("AFK"); return 0; }
这道题不禁让我想起了有一次我决定坐狮鹫去远方看一看,然后就到了部落的领地
被等级是特殊符号的NPC和狮鹫围殴致死
为了联盟!!!