传送门

算法
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. 置换检验(Permutation Test)学习[转载]

    转自:https://www.cnblogs.com/bnuvincent/p/6813785.html http://www.bioinfo-scrounger.com/archives/564 1 ...

  2. Java多线程的下载器(1)

    实现了一个基于Java多线程的下载器,可提供的功能有: 1. 对文件使用多线程下载,并显示每时刻的下载速度. 2. 对多个下载进行管理,包括线程调度,内存管理等. 一:单个文件下载的管理 1. 单文件 ...

  3. Tesseract-OCR 训练过程 V3.02

    软件: jTessBoxEditor Version 0.9 (30 April 2013) Tesseract-OCR win32 v3.02 with Leptonica   训练步骤:   1. ...

  4. keras之save & reload model

    import numpy as np np.random.seed(1337) # for reproducibility from keras.models import Sequential fr ...

  5. 【环境变量】删掉centos原有的openjdk并安装sun jdk

    一.卸载原有openjdk rpm -qa | grep java 之后,将展示出来的全部卸载掉,我这里是5个 rpm -e --nodeps java-1.7.0-openjdk-1.7.0.111 ...

  6. SV中的覆盖率

    SV采用CRT的激励形式,而判断验证进度的标准也就是覆盖率(coverage). 覆盖率的两种指定形式:显式的,直接通过SV来指定出的,如SVA,covergroup. 隐式的,在验证过程中,随&qu ...

  7. Ignite内存数据库与sql支持

    Ignite采用h2作为内存数据库,支持h2的一切sql语法.如果是本地缓存或者复制缓存,sql执行直接在本地h2数据库中执行,如果是分区缓存,ignite则会分解sql到多个h2数据库执行后再汇总. ...

  8. linux常用命令:ifconfig 命令

    许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).通常需 ...

  9. 好用的在线web页面测试,移动页面测试工具webpagetest使用图文教程

    好用的在线web页面测试,移动页面测试工具webpagetest使用图文教程 http://www.webpagetest.org/ 1.打开主页,输入网址,点击 START TEST 按钮开始测试 ...

  10. 面试问题整理之python测试

    1.下列哪个语句在Python中是非法的? A.x = y = z =1 B.x = (y = z + 1) C.x, y = y, x D.x += y 答案:B 2.关于Python内存管理,下列 ...