通往奥格瑞玛的道路
题目背景
在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量
有一天他醒来后发现自己居然到了联盟的主城暴风城
在被众多联盟的士兵攻击后,他决定逃回自己的家乡奥格瑞玛
题目描述
在艾泽拉斯,有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<cstring>
#include<queue>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn = 200000;
int n,m,b;
struct edge{
int t,w,next;
}e[maxn];
int head[maxn],d[maxn];
int cnt;
int inq[maxn];
void insert(int s,int t,int w)
{
e[++cnt].t = t;
e[cnt].w = w;
e[cnt].next = head[s];
head[s] = cnt;
}
int p[maxn];
bool check(int zat){
queue<int> Q;
Q.push(1);
memset(d,0x3f,sizeof(d));
memset(inq,0,sizeof(inq));
inq[1] = 1;
d[1] = 0;
while(!Q.empty()){
int x = Q.front();Q.pop();
inq[x] = 0;
for(int i = head[x];i != 0;i = e[i].next){
if(p[e[i].t] <= zat){
if(d[e[i].t] > d[x] + e[i].w){
d[e[i].t] = d[x] + e[i].w;
if(!inq[e[i].t]){
Q.push(e[i].t);
inq[e[i].t] = 1;
}
}
}
}
}
return (d[n] < b);
}
int main()
{
scanf("%d%d%d",&n,&m,&b);
for(int i = 1;i <= n;i++) scanf("%d",&p[i]);
for(int i = 1;i <= m;i++){
int s,t,w;
scanf("%d%d%d",&s,&t,&w);
insert(s,t,w);
insert(t,s,w);
}
int L = p[1];int R = 1e9;
while(R>L){
int m = (R+L)/2;
if(check(m)){
R = m;
}else L = m+1;
}
if(L == 1e9) printf("AFK\n");
else printf("%d",L);
return 0;
}

浙公网安备 33010602011771号