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; //输出终点到起点的做短距离
}