传送门

算法
Dijkstra
要求次短路

那么在不考虑重复走一条边的情况下

肯定是把最短路中的一段改成另一段

至少要换另一条边到路径里
所以可以枚举所有不属于最短路的每条边(a,b)

那么dis(1,a)+(a,b)+ dis(b,n)就是一种可能的答案(记为S)

显然如果另一条不属于S的边更新S后会使S更长,就不可能为次短路了

那么只要对起点1和终点n分别跑Dijkstra就可以求出每个dis(1,a)和dis(b,n)

至于判断一条边是否在最短路上也很容易:

显然,如果dis(1,a)+(a,b)=dis(1,b),那么边(a,b)就在最短路径上

然后考虑重复走一条边情况(显然也只要考虑重复走一条边的情况)

也很简单,用贪心的思想

找到最短路径上最短的边(a,b),如果重复走一条边的情况为次短路,那么肯定是dis(1,n)+(a,b)*2 (走过去又走回来,要乘2)

如果(c,d)不是最短的边,那么dis(1,n)+(c,d)*2肯定大于dis(1,n)+(a,b)*2,就不可能是次短路

然后就可以了,实现时要注意一下细节

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
inline int read()
{
int res=;
char ch=getchar();
while(ch>''||ch<'')
ch=getchar();
while(ch>=''&&ch<='')
{
res=res*+ch-'';
ch=getchar();
}
return res;
}
struct node//存Dijkstra的优先队列中的数据
{
int u,v;//v为点的编号,u表示从起点到v的距离
bool operator < (const node &b) const{
return u>b.u;
}
};
priority_queue <node> q;//为Dijkstra开的优先队列
struct edge
{
int from,to,z;
}e[];
int fir[],cnt;//链式前向星存图
inline void add(int a,int b,int c)
{
e[++cnt].from=fir[a];
fir[a]=cnt;
e[cnt].to=b;
e[cnt].z=c;
}//加边
int n,m,ans=;
int dis[][];
//dis[][0]为起点到各个点的距离,dis[][1]为终点到各个点的距离
inline void dijk(int sta,int k)
//sta为开始点,k为dis的第二维
{
dis[sta][k]=;
node p;
p.u=; p.v=sta;
q.push(p);
while(q.empty()==)
{
int u=q.top().u,v=q.top().v;
q.pop();
if(u!=dis[v][k]) continue; //优化
for(int i=fir[v];i;i=e[i].from)
{
int to=e[i].to;
if(dis[to][k]>dis[v][k]+e[i].z)
{
dis[to][k]=dis[v][k]+e[i].z;
p.u=dis[to][k]; p.v=to;
q.push(p);
}
}
}
}//Dijkstra的模板
struct data
{
int x,y,z;
}d[];//存读入的数据
int main()
{
memset(dis,0x7f,sizeof(dis));
int a,b,c,mi=;//mi表示最短路径上最短的边长
cin>>n>>m;
for(int i=;i<=m;i++)
{
a=read(); b=read(); c=read();
d[i].x=a; d[i].y=b; d[i].z=c;
add(a,b,c); add(b,a,c);
}//读入
dijk(,); dijk(n,);//跑最短路
int mx=dis[n][];
for(int i=;i<=m;i++)
//考虑不重复走一条边的情况
{
int x=d[i].x,y=d[i].y;
if(dis[x][]+dis[y][]>dis[y][]+dis[x][]) swap(x,y);
//重要的细节,1到x的路径不能和y到n的路径重复
int s=dis[x][]+dis[y][];
if(s+d[i].z==mx) continue;//判断边(x,y)是否在最短路径上,如果在就不能选
ans=min(ans,s+d[i].z);//否则就尝试更新答案
}
for(int i=;i<=m;i++)
//考虑重复走一条边的情况,显然只要考虑在最短路径上的边
{
int x=d[i].x,y=d[i].y;
if(dis[x][]+dis[y][]>dis[y][]+dis[x][]) swap(x,y);
//同样,1到x的路径不能和y到n的路径重复
if(dis[x][]+dis[y][]+d[i].z!=mx) continue;//如果边(x,y)不在最短路径上就不能考虑
mi=min(mi,d[i].z);//尝试更新mi
}
ans=min(ans,mx+mi*);//答案取较小值
cout<<ans;
return ;
}

P2865 【[USACO06NOV]路障Roadblocks】(次短路)的更多相关文章

  1. 洛谷P2865 [USACO06NOV]路障Roadblocks——次短路

    给一手链接 https://www.luogu.com.cn/problem/P2865 这道题其实就是在维护最短路的时候维护一下次短路就okay了 #include<cstdio> #i ...

  2. P2865 [USACO06NOV]路障Roadblocks

    P2865 [USACO06NOV]路障Roadblocks 最短路(次短路) 直接在dijkstra中维护2个数组:d1(最短路),d2(次短路),然后跑一遍就行了. attention:数据有不同 ...

  3. 洛谷——P2865 [USACO06NOV]路障Roadblocks

    P2865 [USACO06NOV]路障Roadblocks 题目描述 Bessie has moved to a small farm and sometimes enjoys returning ...

  4. 络谷 P2865 [USACO06NOV]路障Roadblocks

    P2865 [USACO06NOV]路障Roadblocks 题目描述 Bessie has moved to a small farm and sometimes enjoys returning ...

  5. luogu2865 [USACO06NOV]路障Roadblocks 次短路

    注意:如果是这么个写法,堆数组要开成n+m的. 为什么呢?设想一下从1到2有m条长度递减的路,这岂不是要入队m次-- #include <algorithm> #include <i ...

  6. POJ——T 3255 Roadblocks|| COGS——T 315. [POJ3255] 地砖RoadBlocks || 洛谷—— P2865 [USACO06NOV]路障Roadblocks

    http://poj.org/problem?id=3255 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15680   ...

  7. 【洛谷 P2865】 [USACO06NOV]路障Roadblocks(最短路)

    题目链接 次短路模板题. 对每个点记录最短路和严格次短路,然后就是维护次值的方法了. 和这题一样. #include <cstdio> #include <queue> #in ...

  8. 洛谷题解 P2865 【[USACO06NOV]路障Roadblocks】

    链接:https://www.luogu.org/problemnew/show/P2865 题目描述 Bessie has moved to a small farm and sometimes e ...

  9. BZOJ 1726 洛谷 2865 [USACO06NOV]路障Roadblocks【次短路】

    ·求1到n的严格次短路. [题解] dijktra魔改?允许多次入队,改了次短路的值也要入队. #include<cstdio> #include<algorithm> #de ...

随机推荐

  1. Django之分页功能

    Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表.元组或其它可迭代的对象. 基本语法 class Paginator(ob ...

  2. NPOI 导出excel 分表

    /// <summary> /// 由DataTable导出Excel[超出65536自动分表] /// </summary> /// <param name=" ...

  3. CMPXCHG指令

    一.CMPXCHG汇编指令详解. 这条指令将al\ax\eax\rax中的值与首操作数比较: 1.如果相等,第2操作数的直装载到首操作数,zf置1.(相当于相减为0,所以0标志位置位) 2.如果不等, ...

  4. zw版【转发·台湾nvp系列Delphi例程】HALCON ZoomImageFactor

    zw版[转发·台湾nvp系列Delphi例程]HALCON ZoomImageFactor procedure TForm1.Button1Click(Sender: TObject);var ima ...

  5. 深入理解 Java 内存模型(一)- 内存模型介绍

    深入理解 Java 内存模型(一)- 内存模型介绍 深入理解 Java 内存模型(二)- happens-before 规则 深入理解 Java 内存模型(三)- volatile 语义 深入理解 J ...

  6. “System.Data”中不存在类型或命名空间名称“TypedTableBase”

    错误 1 命名空间“System.Data”中不存在类型或命名空间名称“TypedTableBase”(是否缺少程序集引用?)  解决方案 因为是把强类型DataSet文件绑定报表的项目中出现的错误, ...

  7. Android (Android Studio)无法启动adb 解决方案

    打开cmd 输入:     netstat -aon|findstr "5037"      回车  taskkill /pid xxxx /f     ps:xxxx为占用端口 ...

  8. hive 配置参数说明(收藏版)

    问题导读: 如何设置reduce的个数? Hive 默认的数据文件存储路径? Hive 默认的输出文件格式? 是否开启 map/reduce job的并发提交? 所允许的最大的动态分区的个数? hiv ...

  9. iPhone手机获取uuid 安装测试app

    iPhone手机获取uuid 安装测试app UDID是一种iOS设备的特殊识别码.除序号之外,每台ios装置都另有一组独一无二的号码,我们就称之为识别码( Unique Device Identif ...

  10. Centos6版本使用yum报错 Loaded plugins: fastestmirror, refresh-packagekit, security Loading mirror speeds from cached hostfi Setting up Install Process No package gcc available. Error: Nothing to do

    在使用Centos6版本yum时报错 Loaded plugins: fastestmirror, refresh-packagekit, securityLoading mirror speeds ...