SPFA算法是解决最短路问题的算法
今天来回顾一下单源最短路的问题:
利用SPFA算法可以高效的解决单源最短路问题,并且解决有无负环的问题
如该无向图所示:
假设我们的单源点是1
Part one:
我们先把1压入队列
队列q:[1][][][][][][][]
然后进入while(!q.empty())
把1出队,得到和1相连的点的最短距离
假设w代表边权
if(dis[2]>dis[1]+1-->2.w)
dis[2]=dis[1]+1-->2.w
if(!vis[2])//代表2没有在队列里
{
vis[2]=1 //表示2即将入队
q.push(2)//就将2入队
}//循环会进行三次,因为1连接了三个点
[2][7][6][][][]
并得到最初从单源点到2,7,6的距离
dis[2] dis[7] dis[6]
Part two:
接下来每个点进行循环操作
while(!q.empty())//当无法更新时,队列会逐渐变空
{
int x=q.front();
q.pop();
vis[x]=0 ;//该点出了队列,所以不在队列中
for(int i=0;i<vec[x].size();i++)
{
int v=vec[x][i].to;
int w=vec[x][i].w;
if(dis[v]>dis[x]+w)
{
dis[v]=dis[x]+w;
if(!vis[v])//判断该点是否在队列中如果不在,入队即可
{vis[v]=1;
q.push(v);
}
}
}
板子代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 1005
struct node
{
int v;//终点
int w;//权值
}temp;
vector<node>vec[maxn];//建一个图
int n,m;//n个顶点,m条边
int dis[maxn];//代表从u--->s的距离
int vis[maxn];//做标记
void input()//输入
{
int u,v,w;
for(int i=0; i<m; i++)
{
scanf("%d %d %d",&u,&v,&w);
temp.v=v;
temp.w=w;
vec[u].push_back(temp);//建双向边
temp.v=u;
vec[v].push_back(temp);
}
}
void Spfa(int u)//单源点
{
memset(dis,0x3f3f3f3f,sizeof(dis));//赋值为无穷
memset(vis,0,sizeof(vis));//清空数组
queue<int>q;
q.push(u);//入队
//vis[u]=0;
dis[u]=0;
while(!q.empty())//队列非空
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=0; i<vec[x].size();i++)
{
int to=vec[x][i].v;
printf("%d %d %d\n",x,to,vec[x][i].w);
if(dis[to]>dis[x]+vec[x][i].w)
{
dis[to]=dis[x]+vec[x][i].w;
if(!vis[to])
{
vis[to]=1;
q.push(to);
}
}
}
}
}
int main()
{
scanf("%d %d",&n,&m);
input();
Spfa(1);
printf("%d\n",vec[1].size());
int v;
scanf("%d",&v);
printf("%d\n",dis[v]);
}