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

  

转载于:https://www.cnblogs.com/DriverLao/p/8427589.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值