传送门

算法
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. easyUI的datebox添加清空按钮功能

    需要修改源码: 第一步:按下图修改 第二步:按下两图修改(*zh_CN.js)

  2. SQL Expression Language Tutorial 学习笔记一

    http://docs.sqlalchemy.org/en/latest/core/tutorial.html Google 翻译了一下 SQLAlchemy Expression Language, ...

  3. Locust性能测试5-参数化批量注册

    前言 实现场景:所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复. 例如,模拟10用户并发注册账号,总共有100个手机号,要求注册账号不重复,注册完毕后结束测试 准备数据 虚拟用户 ...

  4. iOS 网易彩票-3常见设置

    Navigation导航设置 为了统一管理导航控制器,需要自定义导航控制器MJNavigationController,继承于UINavigationController.分别设置5个Navigati ...

  5. swoole线程和进程

    pstree -a | grep php |   |       `-php server.php   主进程      |   |           |-php server.php   管理线程 ...

  6. ARM中的汇编指令

    Arm指令,32位的指令集,一共有16条的基本指令,每条指令都可以按条件执行, 指令都是32bit的,高四位是条件码[31:28], Thumb指令,16位的指令集,执行效率比arm指令集要低,但是节 ...

  7. APB总线

    APB(Advance Peripheral Bus)是AMBA总线的一部分,从1998年第一版至今共有3个版本. AMBA 2 APB Specfication:定义最基本的信号interface, ...

  8. UVM中的factory机制实现

    首先在Systemverilog中便有对于重载的最基本的支持. 1)定义task/function时,使用virtual关键字.那之后在test_case中调用时,便使用句柄指向的对象的类型而不是句柄 ...

  9. 强大的chrome(1)以acfun为例抓取视频

    chrome很强大,很强大,很强大. 想要了解他的强大呢,就先要掌握一些基本的chrome命令. 1. chrome://flags   可用来启用或者关闭某些chrome的体验特性   2. chr ...

  10. 由于防火墙限制无法访问linux服务器上的tomcat应用

    使用的是CentOS6.4系统. 问题重现: tomcat服务是启动的, 但无法访问服务器上的tomcat应用页面. 解决办法: 在防火墙配置中设置端口: 命令: # cd /etc/sysconfi ...