洛谷 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;	
}

  

posted @ 2018-02-07 17:15  Driver_Lao  阅读(219)  评论(0编辑  收藏  举报