• P2865 Roadblocks(严格次短路)


    https://www.luogu.com.cn/problem/P2865
    https://loj.ac/problem/10076

    (1)(n) 的严格次短路

    考虑使用 dij
    记录两个数组,dis[u],dis2[u] 分别表示 (1)(u) 的最短路,严格次短路
    更新时,取出堆顶的节点 (u),设它在堆种的距离大小是 (now\_dis)(不是那两个数组里的值),遍历所以和它相邻的节点 (v)

    • (dis_v>now_dis+W_i),那就先 (dis2_v=dis_v),就是当前的最短路变成了严格次短路,然后再中 (v) 更新 (u),最后把 (dis_v,dis2_v) 都放入堆里
    • 对于其它情况,如果 (dis2_v>now_dis+W_i),且 (now_dis+W_i>dis_v),就只更新 (diw2_v) 并放入堆中,后一个条件是为了保证长度是严格次短

    然后就不像一般的 dij 每个点只更新一次了

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<map>
    #include<iomanip>
    #include<cstring>
    #define reg register
    #define EN std::puts("")
    #define LL long long
    inline int read(){
    	register int x=0;register int y=1;
    	register char c=std::getchar();
    	while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
    	while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
    	return y?x:-x;
    }
    #define N 5005
    #define M 200005
    struct graph{
    	int fir[N],nex[M],to[M],w[M],tot;
    	inline void add(int u,int v,int z){
    		to[++tot]=v;w[tot]=z;
    		nex[tot]=fir[u];fir[u]=tot;
    	}
    }G;
    int n,m;
    struct data{
    	int i,dis;
    }heap[N*20];
    int size;
    int dis[N],dis2[N];
    inline void push(data x){
    	heap[++size]=x;
    	reg int i=size,fa;
    	while(i>1){
    		fa=i>>1;
    		if(heap[fa].dis<=heap[i].dis) return;
    		std::swap(heap[fa],heap[i]);i=fa;
    	}
    }
    inline data pop(){
    	data ret=heap[1];heap[1]=heap[size--];
    	reg int i=1,ls,rs;
    	while((i<<1)<=size){
    		ls=i<<1;rs=ls|1;
    		if(rs<=size&&heap[rs].dis<heap[ls].dis) ls=rs;
    		if(heap[i].dis<=heap[ls].dis) break;
    		std::swap(heap[ls],heap[i]);i=ls;
    	}
    	return ret;
    }
    inline void dij(){
    	push((data){1,0});
    	dis[1]=0;
    	reg int u,v,nowdis;
    	data tmp;
    	while(size){
    		tmp=pop();u=tmp.i;nowdis=tmp.dis;
    		for(reg int i=G.fir[u];i;i=G.nex[i]){
    			v=G.to[i];
    			if(dis[v]>nowdis+G.w[i]){
    				dis2[v]=dis[v];
    				dis[v]=nowdis+G.w[i];
    				push((data){v,dis[v]});
    				push((data){v,dis2[v]});
    			}
    			else if(dis2[v]>nowdis+G.w[i]&&nowdis+G.w[i]>dis[v]){
    				dis2[v]=nowdis+G.w[i];
    				push((data){v,dis2[v]});
    			}
    		}
    	}
    }
    int main(){
    	n=read();m=read();
    	for(reg int x,y,z,i=1;i<=m;i++){
    		x=read();y=read();z=read();
    		G.add(x,y,z);G.add(y,x,z);
    	}
    	std::memset(dis,0x3f,sizeof dis);std::memset(dis2,0x3f,sizeof dis2);
    	dij();
    	printf("%d",dis2[n]);
    	return 0;
    }
    
  • 相关阅读:
    pycharm的background task一直更新index,速度慢的解决方法
    第一章 图像处理基础(直方图、高斯滤波、直方图均衡化)
    下载及配置Python+openCV
    封装axios的接口请求数据方法
    better-scroll封装上拉刷新,下拉加载更多功能
    封装js插件(loading)
    商品列表跳转详情页(项目过程思路)
    setInterval踩坑记
    Vue组件封装(以封装一个button组件为例)
    组件传值的方式
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/13371789.html
Copyright © 2020-2023  润新知