目录
1:spfa算法介绍:
用队列优化,减少了一些不必要的松弛操作,继承了bell-man算法的思想,但是复杂度却很大,算法复杂度是nm的,复杂度较大,一般用来处理负权(无负权时推荐使用dijkstra算法)
2:链式前向星方法代码展示:(代码中的变量一些看不懂,可以去看博主最短路算法篇章中的其他文章,已经做过介绍了,就不多说了,其实是懒哈)
#include<bits/stdc++.h>
using namespace std;
//spfa算法
const int N=1e5+10;
int e[N],w[N],ne[N],h[N],cnt=1;
int n,m,s;
bool st[N];
int dis[N];
void add(int a,int b,int c)
{
e[cnt]=b;
w[cnt]=c;
ne[cnt]=h[a];
h[a]=cnt;
cnt++;
}
int main()
{
cin>>n>>m>>s;
while(m--){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
queue<int>q;
memset(dis,0x3f,sizeof(dis));//将dis全部初始化为无穷大
dis[s]=0;
st[s]=1;
q.push(s);//将起点放入队列中,开始进行spfa算法
while(!q.empty()){
int u=q.front();
q.pop();
st[u]=0;//出队清除标记
for(int i=h[u];i;i=ne[i]){
int j=e[i];//i是边的编号,j现在是终点的编号
if(dis[j]>dis[u]+w[i]){
dis[j]=dis[u]+w[i];
if(!st[j]){
st[j]=1;
q.push(j);
}
}
}
}
for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
return 0;
}
3:vector建立邻接图方法代码展示
#include<bits/stdc++.h>
using namespace std;
//用vector写spfa算法
int n,m,s;
const int N=1e5+10;
bool st[N];
typedef struct{
int v,w;
}node;
vector<node>mp[N];
int dis[N];
int main()
{
cin>>n>>m>>s;
while(m--){
int a,b,c;
cin>>a>>b>>c;
node u;
u.v=b;
u.w=c;
mp[a].push_back(u);
}
//开始进行spfa算法
queue<int>q;
q.push(s);
st[s]=1;
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
while(!q.empty()){
int u=q.front();
st[u]=0;
q.pop();
for(int i=0;i<mp[u].size();i++){
if(dis[mp[u][i].v]>dis[u]+mp[u][i].w){
dis[mp[u][i].v]=dis[u]+mp[u][i].w;
if(!st[mp[u][i].v]){
st[mp[u][i].v]=1;
q.push(mp[u][i].v);
}
}
}
}
for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
return 0;
}