题解 P1462 【通往奥格瑞玛的道路】
George1123 · · 题解
P1462 【通往奥格瑞玛的道路】
此题算法:Dijkstra与他的二分
大致思路:
1.
输入 i 站收费f[i] ,求出二分范围l ,起点和终点的费用最大值,和r ,所有的城市收费最大值。2.
二分。只用不高于 mid 的收费站。二分条件:最少耗血是否小于最大血量。3.
输出答案 l 。
以下是代码加注释
#include<bits/stdc++.h>
using namespace std;
#define ong long long
const int N=10010;
const int M=100010;
const ong inf=LLONG_MAX/3; //小心爆long long
int n,m,b,u,v;
int l,r,mid;
ong wi; //爆int了
struct node{
int a;
ong dis;
};
bool operator < (node x,node y){
return x.dis>y.dis;
} priority_queue<node> q;
int top,g[N],f[N];
ong dis[N];
bool vis[N];
struct edge{
int adj,nex;
ong w;
}e[M];
void add(int x,int y,ong wor){
e[++top]=(edge){y,g[x],wor};
g[x]=top;
} void Dijkstra(int maxn){
for(int i=1;i<=n;i++){
dis[i]=inf;
vis[i]=0;
} dis[1]=0;
while(!q.empty()) q.pop();
q.push((node){1,dis[1]});
while(!q.empty()){
node now=q.top(); q.pop();
int x=now.a;
if(vis[x]) continue;
vis[x]=1;
for(int i=g[x];i;i=e[i].nex){
int p=e[i].adj;
if(f[p]>maxn) continue;
if(dis[x]+e[i].w<dis[p]){
dis[p]=dis[x]+e[i].w;
q.push((node){p,dis[p]});
}
}
}
} int main(){
scanf("%d%d%d",&n,&m,&b);
for(int i=1;i<=n;i++){
scanf("%d",f+i);
r=max(r,f[i]);
} l=max(f[1],f[n]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&wi);
add(u,v,wi);
add(v,u,wi);
} while(l<r){
mid=(l+r)>>1;
Dijkstra(mid);
if(dis[n]>b)
l=mid+1; //怕死循环
else r=mid;
} Dijkstra(l);
if(dis[n]>b) printf("AFK\n");
else printf("%d\n",l);
return 0;
}
最后我想说:我太蒟了!
谢谢大家! !