zoukankan      html  css  js  c++  java
  • 洛谷P2865

    感觉此题可作为严格次短路的模板,因此来写一写

    Description

    给定 (n) 个点,(r) 条双向道路,求从 (1) 号点到 (n) 号点的严格次短路

    Solution

    维护两个变量,最短路和次短路

    (Dis[i][0]) 表示从 (1) 号点到 (i) 号点的最短路,(Dis[i][1]) 表示从 (1) 号点到 (i) 号点的次短路

    然后考虑什么情况下会对最短路或次短路的更新造成影响

    (fr) 是当前节点,(to) 是当前节点连出去的某个节点

    (Dis[to][0]>Dis[fr][0]+e[i].dis) 时,表明当前点 (to) 的最短路不再是最短的,就把当前最短路更新成次短路,然后再更新最短路

    (Dis[to][1]>Dis[fr][1]+e[i].dis) 时,发现当前点 (to) 的次短路可以更短,但对最短路无影响,就只更新次短路

    (Dis[to][1]>Dis[fr][0]+e[i].dis) 并且 (Dis[to][0]<Dis[fr][0]+e[i].dis) 时,表明当前点 (to) 的次短路可以更新,而最短路已经是最优,则只更新次短路

    综上,每次按上述方法更新每条边,就可以求出到每个点的严格次短路

    最后答案就是 (Dis[n][1])

    Code

    #include<queue>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define maxn 5010
    #define LL long long
    #define uLL unsigned long long
    
    using namespace std;
    
    queue<int> q;
    int n,r,tot,head[maxn];
    int Dis[maxn][3],vis[maxn];
    struct edge{int fr,to,dis,nxt;}e[maxn<<1];
    
    inline int read(){
    	int s=0,w=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+ch-'0',ch=getchar();
    	return s*w;
    }
    
    inline void add(int fr,int to,int dis){
    	e[++tot].fr=fr;e[tot].to=to;
    	e[tot].dis=dis;e[tot].nxt=head[fr];
    	head[fr]=tot;
    }
    
    inline void SPFA(){
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=head[u];i;i=e[i].nxt){
    			int to=e[i].to,dis=e[i].dis; 
    			if(Dis[to][0]>Dis[u][0]+dis){
    				Dis[to][1]=Dis[to][0];
    				Dis[to][0]=Dis[u][0]+dis;
    				if(!vis[to]) vis[to]=1,q.push(to);
    			}
    			if(Dis[to][1]>Dis[u][1]+dis){
    				Dis[to][1]=Dis[u][1]+dis;
    				if(!vis[to]) vis[to]=1,q.push(to); 
    			}
    			if(Dis[to][1]>Dis[u][0]+dis&&Dis[to][0]<Dis[u][0]+dis){
    				Dis[to][1]=Dis[u][0]+dis;
    				if(!vis[to]) vis[to]=1,q.push(to);
    			}
    		}
    	}
    }
    
    int main(){
    	n=read();r=read();
    	memset(Dis,63,sizeof Dis); 
    	q.push(1);vis[1]=1;Dis[1][0]=0; 
    	for(int i=1,fr,to,dis;i<=r;i++){
    		fr=read();to=read();dis=read();
    		add(fr,to,dis);add(to,fr,dis);
    	}
    	SPFA();printf("%d",Dis[n][1]);
    	return 0;
    }
    
  • 相关阅读:
    多线程 java 同步 、锁 、 synchronized 、 Thread 、 Runnable
    装饰设计模式 Decorator
    Java File IO 字节字符流
    觉得 eclipse 不好用的,了解一下快捷键,辅助快捷输入 类创建方式
    Power builder PB 使用 相关记录
    java 多态 深入理解多态-隐藏-低调-伪装
    Idea 出现 Error:java: Compilation failed: internal java compiler error
    Access 导入到 SQLServer
    20200117 .net 001
    Android ConstraintLayout详解(from jianshu)
  • 原文地址:https://www.cnblogs.com/KnightL/p/14248820.html
Copyright © 2011-2022 走看看