欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

单源最短路径(SPFA)

程序员文章站 2023-12-24 10:32:51
...

单源最短路径

题目背景
本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779。
题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式
第一行包含三个整数 n,m,s分别表示点的个数、有向边的个数、出发点的编号。
接下来 m 行每行包含三个整数 u,v,w表示一条 u→v的,长度为 w 的边。
输出格式
输出一行 n 个整数,第 i 个表示 s 到第 i 个点的最短路径,若不能到达则输出 2^31−1。
输入输出样例
输入
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出
0 2 4 3
样例说明:
单源最短路径(SPFA)图片1到3和1到4的文字位置调换
分析
这题我们可以用SPFA的队列模板
可以参考香甜的黄油(SPFA)
AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int n,m,s,x,y,z,x1,tot,hd[1000005],v[100005],f[100005],d[100005];//定大点
struct stu
{
	int to,next,w;
}a[1000005];
void add(int x,int y,int z)//邻接表建立
{
	tot++;
	a[tot].to=y;
	a[tot].w=z;
	a[tot].next=hd[x];
	hd[x]=tot;
}
void spfa(int x)
{
	d[x]=0,v[x]=1;
	queue<int>f;//队列建立
	f.push(x);//入队
	while(!f.empty())//判断队列是否为空
	{
		x1=f.front();//取队首
		f.pop();//弹出队首
		for(int j=hd[x1];j;j=a[j].next)
		 if(d[a[j].to]>d[x1]+a[j].w)//松弛
		  {
			d[a[j].to]=d[x1]+a[j].w;
			if(v[a[j].to]==0)
			{
				v[x1]=1;
				f.push(a[j].to);
			}
		 }
		v[x1]=0;
	} 
}
int main()
{
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);//有向图
	}
	for(int i=1;i<=n;i++)d[i]=2147483647;//赋值
	spfa(s);//用这个点去找
	for(int i=1;i<=n;i++)cout<<d[i]<<' ';
}

谢谢

上一篇:

下一篇: