P3371 【模板】单源最短路径(弱化版)

题目背景

本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779

题目描述

如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。

输入输出格式

输入格式:

第一行包含三个整数N、M、S,分别表示点的个数、有向边的个数、出发点的编号。

接下来M行每行包含三个整数Fi、Gi、Wi,分别表示第i条有向边的出发点、目标点和长度。

输出格式:

一行,包含N个用空格分隔的整数,其中第i个整数表示从点S出发到点i的最短路径长度(若S=i则最短路径长度为0,若从点S无法到达点i,则最短路径长度为2147483647)

输入输出样例

输入样例#1:

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出样例#1:

0 2 4 3

说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=15;

对于40%的数据:N<=100,M<=10000;

对于70%的数据:N<=1000,M<=100000;

对于100%的数据:N<=10000,M<=500000。保证数据随机。

对于真正 100% 的数据,请移步 P4779。请注意,该题与本题数据范围略有不同。

样例说明:图片1到3和1到4的文字位置调换

解题思路:spfa算法是Bellman-Ford算法的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环。spfa最坏情况下复杂度和朴素Bellman-Ford一样为O(|V||E|)。在非负边权图中为了避免出现最坏情况,通常使用效率更加稳定的Dijkstra算法,以及它的堆优化版本。数据较水,直接拿spfa板子水过。spfa思想:每次只需对上一次更新过的点的邻接点进行更新即可,因为上一次更新的点只对其未更新的邻接点有影响,所以无需像bellman-ford算法一样盲目遍历每条边。另外,出队的顶点要标记为false,即出队的那些点仍有可能对前面已更新过的点到源点的距离再进行更新,同时也要保证每个顶点至多在队列中出现1次,避免浪费时间去重复更新。

AC代码:

 #include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+;
const int inf=0x3f3f3f3f;
queue<int> que;vector<int> v1[maxn],v2[maxn];int n,m,s,u,v,w,x,y,z,dis[maxn];bool vis[maxn];
void spfa(int s){
while(!que.empty())que.pop();
que.push(s),vis[s]=true,dis[s]=;
while(!que.empty()){
x=que.front();que.pop(),vis[x]=false;//出队则标记不在队列中
for(size_t j=;j<v1[x].size();++j){
y=v1[x][j],z=v2[x][j];
if(dis[x]+z<dis[y]){
dis[y]=dis[x]+z;
if(!vis[y])que.push(y),vis[y]=true;//标记在队列中
}
}
}
}
int main(){
while(cin>>n>>m>>s){
for(int i=;i<=n;++i)v1[i].clear(),v2[i].clear();
memset(vis,false,sizeof(vis));
while(m--){
cin>>u>>v>>w;
v1[u].push_back(v);//邻接点
v2[u].push_back(w);//对应边权
}
memset(dis,0x3f,sizeof(dis));
spfa(s);
for(int i=;i<=n;++i)cout<<(dis[i]==inf?:dis[i])<<(i==n?'\n':' ');
}
return ;
}

P4779 【模板】单源最短路径(标准版)

题目背景

2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。

然后呢?

100→60;

Ag→Cu;

最终,他因此没能与理想的大学达成契约。

小 F 衷心祝愿大家不再重蹈覆辙。

题目描述

给定一个 N 个点,M条有向边的带非负权图,请你计算从S出发,到每个点的距离。

数据保证你能从S出发到任意点。

输入格式:

第一行为三个正整数 N, M, S。 第二行起 M 行,每行三个非负整数 $u_i$, $v_i$, $w_i$​,表示从 $u_i$​ 到 $v_i$​ 有一条权值为 $w_i$​ 的边。

输出格式:

输出一行N个空格分隔的非负整数,表示S到每个点的距离。

输入样例#1:

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

输出样例#1:

0 2 4 3
说明
样例解释请参考 数据随机的模板题。

1≤N≤100000;

1≤M≤200000;

S=1;

1≤ui​,vi​≤N;

0≤wi​≤10^9,

0≤∑wi​≤10^9。

本题数据可能会持续更新,但不会重测,望周知。

2018.09.04 数据更新 from @zzq

解题思路:堆优化Dijkstra算法,其实就是降低了每次去查找当前dis数组中最小值的时间,时间复杂度由原来的O(|V|2)降为O(|E|log|V|)。对于此题,spfa已死,T到爆!

AC代码:

 #include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+;
int n,m,s,u,v,w,x,y,z,dis[maxn];vector<int> v1[maxn],v2[maxn];bool vis[maxn];
priority_queue< pair<int,int> > que;//最大堆优先队列
void Dijkstra(){
while(!que.empty())que.pop();
memset(vis,false,sizeof(vis));
dis[s]=;que.push(make_pair(-dis[s],s));//加上负号实现最大堆,便于取出最短路径
while(!que.empty()){
x=que.top().second;que.pop();
if(vis[x])continue;//过滤掉已归纳到最短距离集合的点
vis[x]=true;//归纳该点到最短路径的集合
for(size_t j=;j<v1[x].size();++j){//松弛
y=v1[x][j],z=v2[x][j];
if(!vis[y]&&(dis[x]+z<dis[y]))dis[y]=dis[x]+z,que.push(make_pair(-dis[y],y));
}
}
}
int main(){
while(~scanf("%d%d%d",&n,&m,&s)){
for(int i=;i<=n;++i)v1[i].clear(),v2[i].clear();
for(int i=;i<=n;++i)dis[i]=2e9;
while(m--){
scanf("%d%d%d",&u,&v,&w);
v1[u].push_back(v);//邻接点
v2[u].push_back(w);//边权
}
Dijkstra();
for(int i=;i<=n;++i)printf("%d%c",dis[i],i==n?'\n':' ');
}
return ;
}

luogu P3371 & P4779 单源最短路径spfa & 最大堆优化Dijkstra算法的更多相关文章

  1. [C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)

    1 Dijkstra算法 1.1 算法基本信息 解决问题/提出背景 单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径) 算法思想 贪心算法 按路径长度递增的次序,依次产生最短路径的算法 ...

  2. 单源最短路径(1):Dijkstra 算法

    一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...

  3. 【Luogu P3371&P4779】【模板】单源最短路径(线段树优化Dijkstra)

    线段树优化$\rm dijkstra$ 线段树每个节点维护$[l,r]$中$dist$最小的点,删除则把该点$dist$赋值为$+\infty$,然后更新该点影响到的线段树上的其他节点即可. 可以得到 ...

  4. 洛谷P3371单源最短路径SPFA算法

    SPFA同样是一种基于贪心的算法,看过之前一篇blog的读者应该可以发现,SPFA和堆优化版的Dijkstra如此的相似,没错,但SPFA有一优点是Dijkstra没有的,就是它可以处理负边的情况. ...

  5. Luogu P4779 【模板】单源最短路径(标准版)(Dijkstra+堆优化模板)

    qwq dij其实和prim挺像的,prim是找权值最小点,dij是找边, 用一个优先队列就可以在加入边的时候直接排序,避免了每次遍历更新min priority_queue <pair< ...

  6. 单源最短路径spfa模板(pascal)洛谷P3371

    题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三 ...

  7. 洛谷 P3371 【模板】单源最短路径(弱化版) && dijkstra模板

    嗯... 题目链接:https://www.luogu.org/problem/P3371 没什么好说的,这是一个最短路的模板,这里用的dijkstra做的... 注意: 1.dijkstra和邻接表 ...

  8. 洛谷 P4779 单源最短路径(标准版) 题解

    题面 这道题就是标准的堆优化dijkstra: 注意堆优化的dijkstra在出队时判断vis,而不是在更新时判断vis #include <bits/stdc++.h> using na ...

  9. AOJ GRL_1_B: Shortest Path - Single Source Shortest Path (Negative Edges) (Bellman-Frod算法求负圈和单源最短路径)

    题目链接: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_B   Single Source Shortest Path ...

随机推荐

  1. hibernate预编译SQL语句中的setParameter和setParameterList

    使用预编译SQL语句和占位符參数(在jdbc中是?),可以避免由于使用字符串拼接sql语句带来的复杂性.我们先来简单的看下.使用预编译SQL语句的优点. 使用String sql = "se ...

  2. Java,如何获取文件的MD5值

    MessageDigest类封装得很不错,简单易用 不多说,直接上代码 import java.io.FileInputStream;import java.security.MessageDiges ...

  3. SpringBoot启动跟踪

    程序启动入口 @SpringBootApplication public class Chapter001Application { public static void main(String[] ...

  4. hihocoder 1015 KMP(找多个位置的 【*模板】)

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  5. POJ3252 Round Numbers —— 数位DP

    题目链接:http://poj.org/problem?id=3252 Round Numbers Time Limit: 2000MS   Memory Limit: 65536K Total Su ...

  6. POJ1511 Invitation Cards —— 最短路spfa

    题目链接:http://poj.org/problem?id=1511 Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Tota ...

  7. poj 1258 Agri-Net 解题报告

    题目链接:http://poj.org/problem?id=1258 题目意思:给出 n 个 farm,每个farm 之间通过一定数量的fiber 相连,问使得所有farm 直接或间接连通的 最少 ...

  8. html5--6-24 css3前缀

    html5--6-24 css3前缀 学习要点 掌握css3前缀的使用 CSS3目前很多新增属性尚未被W3C列为标准,对这些暂时未被公布为标准的属性,各家浏览器会在属性前加上前缀词,也将其称之为浏览器 ...

  9. 在canvas标签和style中定义width和height

    在canvas标签中定义width.height跟在style中定义width.height是不同的.canvas标签的width和height是画布实际宽度和高度,就是在这个上面绘制图形.style ...

  10. 西门子PLC存储器、地址区

    S7-1500 CPU的存储器 1.内部集成的存储器:工作存储器,保持性存储器,系统存储器 2.外插的SIMATIC存储卡:装载存储器去 装载存储器:断电信息不丢失,主要存储项目中程序块,数据块,工艺 ...