单源最短路
dis数组存距离 其步骤和迪杰斯特拉我觉得差不多
落谷例题
本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779。
题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式
第一行包含三个整数 n,m,sn,m,s,分别表示点的个数、有向边的个数、出发点的编号。
接下来 mm 行每行包含三个整数 u,v,wu,v,w,表示一条 u \to vu→v 的,长度为 ww 的边。
输出格式
输出一行 nn 个整数,第 ii 个表示 ss 到第 ii 个点的最短路径,若不能到达则输出 2^{31}-12
31
−1。
这个方法使用了邻接表存图
我们也可以用vector存图
/*
spfa
5/13
*/
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<queue>
#define inf 2147483647
//0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
ll n,m,k;
ll cnt=0;
ll mod=80112002;
const int maxn=1e6+199;
struct node{
int u,v,w,next;
}e[maxn];
int head[maxn];
ll dis[maxn]; // ju
int vis[maxn]; // d
void add(int u,int v,int w){
e[++cnt].next=head[u]; //指向上一个u
e[cnt].v=v;
e[cnt].w=w;
head[u]=cnt;
}
void spfa(int str){
queue<int>q;
dis[str]=0;
vis[str]=1;
q.push(str);
while(q.size()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(dis[u]+e[i].w<dis[v]){
dis[v]=dis[u]+e[i].w; // 如果dis[u]加到该点的距离大于原来的dis[v] 就更新一下
if(!vis[v]){
q.push(v);
vis[v]=1;//入队标记1
}
}
}
vis[u]=0; //出队标记0
}
}
int main(){
int str;
cin>>n>>m>>str;
for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
spfa(str);
for(int i=1;i<=n;i++){
cout<<dis[i]<<' ';
}
return 0;
}
/*
dijkstra
5/14
*/
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<queue>
#define inf 2147483647
//0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
ll n,m,k;
ll cnt=0;
ll mod=80112002;
const int maxn=1e6+199;
struct node{
int u,v,w,next;
}e[maxn];
int head[maxn];
ll dis[maxn]; // ju
int vis[maxn]; // d
void add(int u,int v,int w){
e[++cnt].next=head[u];
e[cnt].v=v;
e[cnt].w=w;
head[u]=cnt;
}
void dijkstra(int str){
priority_queue<PII,vector<PII>,greater<PII> >q;
q.push({0,str});
dis[str]=0;
while(q.size()){
PII f=q.top();
q.pop();
int u=f.second;
if(vis[u])
continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].v;
if(dis[u]+e[i].w<dis[v]){
dis[v]=dis[u]+e[i].w;
q.push(make_pair(dis[v],v));
}
}
}
}
int main(){
int str;
cin>>n>>m>>str;
for(int i=1;i<=n;i++) dis[i]=inf;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
dijkstra(str);
for(int i=1;i<=n;i++){
cout<<dis[i]<<' ';
}
return 0;
}