p1462 通往奥格瑞玛的道路
Posted 水题收割者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了p1462 通往奥格瑞玛的道路相关的知识,希望对你有一定的参考价值。
题目
在艾泽拉斯,有n个城市。编号为1,2,3,...,n。
城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。
每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。
假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。
歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。
输入格式:
第一行3个正整数,n,m,b。分别表示有n个城市,m条公路,歪嘴哦的血量为b。
接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。
再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,会损失ci的血量。
输出格式:
仅一个整数,表示歪嘴哦交费最多的一次的最小值。
如果他无法到达奥格瑞玛,输出AFK。
分析
二分每一次这个人所交的最多费用,求只走小于等于这个值的点所得的以减血量为权值的最短路,如果这个值小于血量则满足要求。对于能否到达我们只需设所交最多费用为一个极大数看是否满足要求即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define pb push_back
#define fi first
#define mp make_pair
#define se second
int d[1100000],vis[1100000],f[1100000],n,m,b;
vector<pair<int,int> >v[20000];
priority_queue<pair<int,int> >q;
bool go(int wh){
int x,y,z;
memset(d,0x3f,sizeof(d));
memset(vis,0,sizeof(vis));
d[1]=0;
q.push(mp(0,1));
while(!q.empty()){
x=q.top().se;
q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=0;i<v[x].size();i++)
if(f[v[x][i].fi]<=wh){
y=v[x][i].fi,z=v[x][i].se;
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(mp(-d[y],y));
}
}
}
if(d[n]>=b)return 0;
return 1;
}
int main(){
int i,j,k,lb,ub=0,x,y,z,ok=0;
cin>>n>>m>>b;
for(i=1;i<=n;i++){
cin>>f[i];
ub=max(ub,f[i]);
}
for(i=1;i<=m;i++){
cin>>x>>y>>z;
v[x].pb(mp(y,z));
v[y].pb(mp(x,z));
}
if(!go(0x3f3f3f3f)){
puts("AFK");
return 0;
}
lb=f[1]-1;
while(ub-lb>1){
int mid=(ub+lb)>>1;
if(go(mid))ub=mid;
else lb=mid;
}
cout<<ub<<endl;
return 0;
}
以上是关于p1462 通往奥格瑞玛的道路的主要内容,如果未能解决你的问题,请参考以下文章