传送门

      ——在LYC大佬的帮助下过了这道题

思路:

  LYC大佬的博客里已经讲得很清晰了,我只是提一下要点。

  求次短路,主要考虑两个方面:

  ①在不重复走一条路的前提下,把最短路的其中一段替换为另一段。

  ②找出最短路中的最短的一条边,重复走两次。(走过来又走回去)

  分别求出这两方面所能算出的次短路的值,取小的那一条就是答案。

补充:

  ①读入的边要开结构体存起来,后面枚举求次短路要使用。

  ②所谓枚举,就是找出从开始一条一条的读出边的两端点、权值。确定其是否在最短路上(即它的 左端点到源点的最短路+右端点到源点的最短路+自身的边权 是否等于最短路长度。(注意细节:要判断这条边的两端点到源点的最短路是否有重合部分,如下图。)

  

  设d[ a ]为 a 到源点的最短路,d[ b ]为 b 到源点的最短路,很显然,两条最短路有重合的地方,就需要将 a 点与 b 点交换位置,使得两条最短路没有重合,才能将 a->b 的权值加入。

代码实现:

        if(d1[x]+d2[y]>d1[y]+d2[x]) swap(x,y);

效果如下:

  

完整代码:

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<deque>
#include<set>
#include<map>
#include<vector>
#include<fstream>
using namespace std;
#define maxn 1000007
struct edge
{
int x,y,w;
}dd[maxn];
struct hh
{
int nex,to,dis;
}t[maxn];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q1;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q2;//正反两次最短路,两个小根堆
int n,m,cnt=,ans,mi;
int vis[maxn],d1[maxn],d2[maxn],head[maxn];
inline int read()
{
char kr=;
char ls;
for(;ls>''||ls<'';kr=ls,ls=getchar());
int xs=;
for(;ls>=''&&ls<='';ls=getchar())
{
xs=xs*+ls-;
}
if(kr=='-') xs=-xs;
return xs;
}
inline void add(int nex,int to,int w)
{
t[++cnt].nex=head[nex];
t[cnt].to=to;
t[cnt].dis=w;
head[nex]=cnt;
}
inline void dijkstra_first(int ww)
{
memset(d1,0x3f3f3f3f,sizeof(d1));
memset(vis,,sizeof(vis));
q1.push(make_pair(,ww));
d1[ww]=;
while(!q1.empty())
{
int u=q1.top().second;
q1.pop();
if(vis[u]) continue;
vis[u]=;
for(int v=head[u];v;v=t[v].nex)
{
if(d1[t[v].to]>d1[u]+t[v].dis&&!vis[t[v].to])
{
d1[t[v].to]=d1[u]+t[v].dis;
q1.push(make_pair(d1[t[v].to],t[v].to));
}
}
}
}
inline void dijkstra_second(int ww)
{
memset(d2,0x3f3f3f3f,sizeof(d2));
memset(vis,,sizeof(vis));
q2.push(make_pair(,ww));
d2[ww]=;
while(!q2.empty())
{
int u=q2.top().second;
q2.pop();
if(vis[u]) continue;
vis[u]=;
for(int v=head[u];v;v=t[v].nex)
{
if(d2[t[v].to]>d2[u]+t[v].dis&&!vis[t[v].to])
{
d2[t[v].to]=d2[u]+t[v].dis;
q2.push(make_pair(d2[t[v].to],t[v].to));
}
}
}
}//两次Dijkstra求正反最短路
int main()
{
n=read();m=read();
ans=;
mi=;
for(int i=;i<=m;++i)
{
dd[i].x=read();dd[i].y=read();dd[i].w=read();
add(dd[i].x,dd[i].y,dd[i].w);
add(dd[i].y,dd[i].x,dd[i].w);
}
dijkstra_first();
dijkstra_second(n);
int minn=d1[n];
for(int i=;i<=m;i++)
{
int x=dd[i].x,y=dd[i].y;
if(d1[x]+d2[y]>d1[y]+d2[x]) swap(x,y);
int s=d1[x]+d2[y];
if(s+dd[i].w==minn) continue;
ans=min(ans,s+dd[i].w);
}//第一点:不重走边
for(int i=;i<=m;i++)
{
int x=dd[i].x,y=dd[i].y;
if(d1[x]+d2[y]>d1[y]+d2[x]) swap(x,y);
if(d1[x]+d2[y]+dd[i].w!=minn) continue;
mi=min(mi,dd[i].w);//找出最短路中最短的边
}//第二点:重走边
ans=min(ans,minn+mi*);//取较小值
printf("%d\n",ans);
return ;
}

其实两遍的Dijkstra函数可以简化为一遍,多打一遍练练模板。

次短路——Dijkstra的更多相关文章

  1. hdu 2544 最短路 Dijkstra

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 题目分析:比较简单的最短路算法应用.题目告知起点与终点的位置,以及各路口之间路径到达所需的时间, ...

  2. 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法

    图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...

  3. 单源最短路dijkstra算法&&优化史

    一下午都在学最短路dijkstra算法,总算是优化到了我能达到的水平的最快水准,然后列举一下我的优化历史,顺便总结总结 最朴素算法: 邻接矩阵存边+贪心||dp思想,几乎纯暴力,luoguTLE+ML ...

  4. HUD.2544 最短路 (Dijkstra)

    HUD.2544 最短路 (Dijkstra) 题意分析 1表示起点,n表示起点(或者颠倒过来也可以) 建立无向图 从n或者1跑dij即可. 代码总览 #include <bits/stdc++ ...

  5. 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

    layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...

  6. 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

    layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...

  7. 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)

    layout: post title: 训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板) author: "luowentaoaa" catalo ...

  8. 最短路Dijkstra算法的一些扩展问题

    最短路Dijkstra算法的一些扩展问题     很早以前写过关于A*求k短路的文章,那时候还不明白为什么还可以把所有点重复的放入堆中,只知道那样求出来的就是对的.知其然不知其所以然是件容易引发伤痛的 ...

  9. 华夏60 战斗机(最短路dijkstra)

    华夏60 战斗机(最短路dijkstra) 华夏60 超音速战斗机是当今世界上机动性能最先进的战斗机.战斗过程中的一个关键问题是如何在最短的时间内使飞机从当前的飞行高度和速度爬升/俯冲到指定的高度并达 ...

  10. Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化)

    Til the Cows Come Home 最短路Dijkstra+bellman(普通+优化) 贝西在田里,想在农夫约翰叫醒她早上挤奶之前回到谷仓尽可能多地睡一觉.贝西需要她的美梦,所以她想尽快回 ...

随机推荐

  1. 初学delphi

    今天女朋友的一门课,要求用delphi 软件编程,内容是一个计算器.当然,这个工作肯定是落在我的头上了. 这个软件是我第一次使用,边自学边进行代码编写,在n多次修改完善之后,终于成形.功能不是很多,跟 ...

  2. jdbc连接 orale 和 mysql 所需要的jar包

    oracle: ojdbc6-12.1.0.2.jar mysql: mysql-connector-java-5.1.47.jar

  3. Spring框架之使用JdbcTemplate开发Dao层程序

    简介: JdbcTemplate开发dao层程序     由Spring框架给我们提供,Spring提供的很多操作数据源(关系型数据库,二维表格模型,有明确的行和列(mysql/orcal等) 非关系 ...

  4. Linux内核启动流程与模块机制

    本文旨在简单的介绍一下Linux的启动流程与模块机制: Linux启动的C入口位于/Linux.2.6.22.6/init/main.c::start_kernel() 下图简要的描述了一下内核初始化 ...

  5. v-bind属性的绑定

    v-bind:属性绑定: 当我们并没有使用v-bind使用的时候,突破不能显示出来,会提示错误,提示我们使用v-bind: 当我们使用v-bind时图片就可以显示: v-bind的简写是冒号: 使用v ...

  6. 关于我在17号“一个查询任意年份中任意月份的天数”程序编写中的代码&第二种方法!

    PS:下面的代码是我对于17号的练习题的一些新的看法(其实就是从另一个角度思考问题) package day20180917;import java.util.Scanner;//导包public c ...

  7. LVS+Keepalived+Mysql+主备数据库架构[4台]

    这是一个坑...磨了不少时间.见证自己功力有待提升... 架构图 数据库 1.安装数据库 这块不难, 直接引用:mysql安装 2.数据库主备 这块不难, 直接引用: mysql主备 虚拟VIP 重点 ...

  8. 一图解释PHPstorm代码片段设置---附官方文档(转)

    参考:https://blog.csdn.net/thinkthewill/article/details/81145106 资料 设置片段[官方设置教程] 设置变量对话框[官方设置教程] phpst ...

  9. 如何将QT的pro图标修改的更显著一些

    如何将QT的pro图标修改的更显著一些 QT的项目打开文件是pro,默认是这样的 这个白色的背景在很多文件中很不好找 所以使用工具进行相关修改. 寻找到.pro 双击修改ico 默认的这个就非常不错. ...

  10. How to install Maven on Windows

    To install Apache Maven on Windows, you just need to download the Maven’s zip file, and Unzip it to ...