洛谷 P2829 大逃离 题解
题目链接
一道模板的次短路
设 d i s [ x ] , d i s t [ x ] dis[x],dist[x] dis[x],dist[x] 分别为点 1 1 1 到 x x x 的最短路和次短路长度
我们只需在跑最短路时,顺带更新一下次短路
由于每个点可以经过多次,我们只能使用 SPFA
对于每条边 [ x , y ] [x,y] [x,y],考虑 d i s t [ y ] dist[y] dist[y] 的转移:
- 最无脑的一种, d i s t [ y ] = d i s t [ x ] + w ( x , y ) dist[y]=dist[x]+w(x,y) dist[y]=dist[x]+w(x,y),其中 w ( x , y ) w(x,y) w(x,y) 为当前边的长度
- 在最短路中,进行松弛操作后,满足当前的 d i s [ y ] dis[y] dis[y] 小于松弛前的 d i s [ y ] dis[y] dis[y]。那么,我们就可以用松弛前的 d i s [ y ] dis[y] dis[y] 去更新 d i s t [ y ] dist[y] dist[y]
- 如果, d i s [ y ] < d i s [ x ] + w ( x , y ) dis[y]<dis[x]+w(x,y) dis[y]<dis[x]+w(x,y),说明 d i s [ x ] + w ( x , y ) dis[x]+w(x,y) dis[x]+w(x,y) 是一条次短路,所以 d i s t [ y ] = m i n ( d i s t [ y ] , d i s [ x ] + w ( x , y ) ) dist[y]=min(dist[y],dis[x]+w(x,y)) dist[y]=min(dist[y],dis[x]+w(x,y))。注意:这里更新的时间是在松弛操作之后
关键代码
for(int i=0;i<e[x].size();++i)
{int y=e[x][i].v;if(d[y]<k && y>1 && y<n)continue;int tmp=dis[x]+e[x][i].len;if(dis[y]>tmp) // 松弛{dist[y]=dis[y]; // 用老的 dis[y] 更新 dist[y]dis[y]=tmp;if(!vis[y])vis[y]=1,q.push(y);}else if(dist[y]>tmp && tmp!=dis[y]) // 如果 dis[x]+e[x][i].len 是一条次短路{dist[y]=tmp;if(!vis[y])vis[y]=1,q.push(y);}if(dist[y]>dist[x]+e[x][i].len){dist[y]=dist[x]+e[x][i].len;if(!vis[y])vis[y]=1,q.push(y);}
}
这里说一下,题目中提到的:一个点所直接连接的地方数量
这里的数量并不等于这个节点的度数(连边数),因为两个节点之间可能有多条边。这才是正确的打开方式:
for(int x=1;x<=n;++x)
{for(int i=0;i<e[x].size();++i){int y=e[x][i].v;if(!vis[y])++d[x];vis[y]=1;}memset(vis,0,sizeof(vis));
}
完整代码
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int Maxn=10010,inf=0x3f3f3f3f;
struct edge{int v,len;edge(int x,int y){v=x,len=y;}
};
int dis[Maxn],dist[Maxn],d[Maxn];
bool vis[Maxn];
int n,m,k;
vector <edge> e[Maxn];
void spfa()
{fill(dis,dis+2+n,inf);fill(dist,dist+2+n,inf);queue <int> q;q.push(1),vis[1]=1,dis[1]=0;while(q.size()){int x=q.front();vis[x]=0;q.pop();for(int i=0;i<e[x].size();++i){int y=e[x][i].v;if(d[y]<k && y>1 && y<n)continue;int tmp=dis[x]+e[x][i].len;if(dis[y]>tmp){dist[y]=dis[y];dis[y]=tmp;if(!vis[y])vis[y]=1,q.push(y);}else if(dist[y]>tmp && tmp!=dis[y]){dist[y]=tmp;if(!vis[y])vis[y]=1,q.push(y);}if(dist[y]>dist[x]+e[x][i].len){dist[y]=dist[x]+e[x][i].len;if(!vis[y])vis[y]=1,q.push(y);}}}
}
int main()
{// freopen("in.txt","r",stdin);scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;++i){int x,y,c;scanf("%d%d%d",&x,&y,&c);e[x].push_back(edge(y,c));e[y].push_back(edge(x,c));}for(int x=1;x<=n;++x){for(int i=0;i<e[x].size();++i){int y=e[x][i].v;if(!vis[y])++d[x];vis[y]=1;}memset(vis,0,sizeof(vis));}spfa();if(dist[n]==inf)puts("-1");else printf("%d\n",dist[n]);return 0;
}
洛谷 P2829 大逃离 题解相关推荐
- 洛谷P2312 解方程题解
洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...
- 洛谷P4568 [JLOI2011] 飞行路线 题解
洛谷P4568 [JLOI2011] 飞行路线 题解 题目链接:P4568 [JLOI2011] 飞行路线 题意: Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公 ...
- 【洛谷P3960】列队题解
[洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...
- 洛谷P4099 [HEOI2013]SAO 题解
洛谷P4099 [HEOI2013]SAO 题解 题目链接:P4099 [HEOI2013]SAO 题意: Welcome to SAO ( Strange and Abnormal Online). ...
- 洛谷P3205 [HNOI2010]合唱队 题解
洛谷P3205 [HNOI2010]合唱队 题解 题目链接:P3205 [HNOI2010]合唱队 题意: 为了在即将到来的晚会上有更好的演出效果,作为 AAA 合唱队负责人的小 A 需要将合唱队的人 ...
- 洛谷 P2700逐个击破 题解 C++
洛谷 P2700逐个击破 题解 C++ 文章目录 洛谷 P2700逐个击破 题解 C++ 题目大意 思路 贪心证明 详细做法 代码 样例 题目大意 给定N个点的一棵树以及N-1条无向边和该边的销毁代价 ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷P1273 有线电视网 题解
洛谷P1273 有线电视网 题解 题目链接:P1273 有线电视网 题意: 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为 ...
- 洛谷P3426 [POI2005]SZA-Template 题解
洛谷P3426 [POI2005]SZA-Template 题解 题目链接:P3426 [POI2005]SZA-Template 题意:你打算在纸上印一串字母. 为了完成这项工作,你决定刻一个印章. ...
最新文章
- IT界惊现文豪!华为领导及阿里P10遭吐槽
- 语音文件转成文字怎么转
- bindservice启动服务
- Matlab从入门到精通-在线性代数中的应用(二):求解齐次线性方程组
- QGraphicsItem获取不到鼠标事件
- java字节数_Java各种类型占用的字节数
- pip安装报错:is not a supported wheel on this platform
- LeetCode 1488. 避免洪水泛滥(贪心+set二分查找)
- 将单链表翻转的两种方法
- python人体识别_Github开源人体姿态识别项目OpenPose中文文档
- WEB浏览器页面上可视化展示JSON数据的方法
- 市场供需简单模型分析
- ASC18世界超算大赛的三大变化与一大不变丨Xtecher观察
- EBU5502 Database Coursework Specifications
- 什么是“决策表”?什么是“决策树”?
- 12306中/otn/HttpZF/logdevice?algID 与 /otn/HttpZF/GetJS 的关系
- USB 3.0硬件设计
- 十二届蓝桥杯Scratch国赛试题
- java解决数独_Java解决“数独”之三
- oracle查看历史oracle database数据库版本并下载
热门文章
- 阿里云栖大会首日:成立芯片公司“平头哥”,发布城市大脑2.0
- 异步编程之美——CompletableFuture
- 2015-07-20-struts-struts2简介
- WiFi(Wireless Fidelity)基础(六)
- Android 11.0 12.0系统默认开启wifi
- 亮考帮优秀作业计算机操作原理,对分课堂教学模式的“亮考帮”怎样在教案设计中分析体现...
- 南京邮电大学图书管理系统
- haproxy 绑定vip问题
- 【深度学习】cs231n计算机视觉 SVM分类器
- Vivado驱动安装