图论—最短路之spfa算法

spfa算法
(bellman算法优化而来)
求图上单源最短路的算法

思路

  • 基于宽度优先搜索(BFS)

  • 考虑目前站在任一点k,则可向前走一步,走一步就有更新最短距离的可能

  • 从起点出发向前试探性的走,队列辅助宽度优先搜索

  • 时间复杂度O(nlogn~n²)

spfa算法需要用到队列的方法

队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头

在这里插入图片描述

队列代码的简单介绍

#include<queue>		//队列需要用到的头文件
#include<bits/stdc++.h>
using namespace std;

int main()
{
	queue<int> q;	//定义了一个int型队列变量q
	q.push(1);		//push函数是向队列队尾中添加元素
	q.push(2);
	q.push(3);

	while(!q.empty())		//判断队列是否为空
	{
		int x=q.front();	//front函数是把队头元素提取出来
		q.pop();	//把队头扔掉
		cout<<x<<endl; 	
	}
}
/*
输出结果是
1
2
3
因为1先入队列,其次是2,最后是三


#include<bits/stdc++.h>
using namespace std;
const int INF=1e9+7;
const int MAXN=1e6+9;


bool inq[MAXN];		//判断i是否在队列中
int dis[MAXN];		//起点到i的距离
int spfa(int s){
	for(int i=0;i<=n;i++){
		inq[i]=false;
		dis[i]=INF;
	}
	dis[s]=0;
	queue<int> q;
	q.push(s);	//起点入列
	while(!q.empty()){      //BFS  宽度优先搜索
		int u=q.front();
		q.pop();
		inq[u]=0;
		for( int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].to;
			if(dis[v]>dis[u]+edge[i].len){
				dis[v]=dis[u]+edge[i].len;
				if(!inq[v]){
					inq[v]=1;
					q.push(v);
				}
			}
		}
	}
}
int main(){	
	spfa(1)	//起点传入队列
	cout<<dis[n]<<endl;	//输出终点到起点的做短距离
}

猜你喜欢

转载自blog.csdn.net/weixin_43916296/article/details/87194304