洛谷 1396 营救 (最短路)
【题意概述】
给出一个n个点m条无向边的图以及起点s终点t,求s到t上的路径上边权最大值的最小值。
【题解】
裸的最短路。把松弛操作稍做修改即可。
#include<cstdio> #include<algorithm> #include<cstring> #define fa (x>>1) #define ls (x<<1) #define rs (x<<1|1) #define rg register #define N (500010) using namespace std; int n,m,s,t,tot,dis[N],last[N],pos[N]; struct edge{int to,pre,dis;}e[N]; struct heap{int to,dis;}h[N]; inline int read(){ int k=0,f=1; char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); return k*f; } inline int max(int x,int y){return x>y?x:y;} inline void add(int x,int y,int z){e[++tot]=(edge){y,last[x],z}; last[x]=tot;} inline void Swap(int x,int y){swap(h[x],h[y]); swap(pos[h[x].to],pos[h[y].to]);} inline void up(int x){while(x>1&&h[fa].dis>h[x].dis) Swap(x,x=fa);} inline void down(int x){ while((ls<=tot&&h[ls].dis<h[x].dis)||(rs<=tot&&h[rs].dis<h[x].dis)){ if(rs<=tot) Swap(x,h[ls].dis<h[rs].dis?x=ls:x=rs); else Swap(x,x=ls); } } inline void dijkstra(int x){ h[pos[x]=tot=1]=(heap){x,dis[x]=0}; while(tot){ int now=h[1].to; h[1]=h[tot--]; if(tot) down(1); for(rg int i=last[now],to;i;i=e[i].pre) if(dis[to=e[i].to]>max(dis[now],e[i].dis)){ dis[to]=max(dis[now],e[i].dis); if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]}; up(pos[to]); } pos[now]=0; } } int main(){ memset(dis,0X7f7f7f7f,sizeof(dis)); n=read(); m=read(); s=read(); t=read(); for(rg int i=1,u,v,d;i<=m;i++) u=read(),v=read(),add(u,v,d=read()),add(v,u,d); dijkstra(t); printf("%d\n",dis[s]); return 0; }