先放上没有优化的的SPFA
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAX 105
#define inf 0xfffffff
int map[MAX][MAX],vis[MAX],dis[MAX],cnt[MAX];
int n,m;
using namespace std;
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) map[i][j]=0;
else map[i][j]=inf;
}
}
void spfa()
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
int i;
for(i=2;i<=n;i++)
dis[i]=inf;
dis[1]=0;
queue<int>q;
q.push(1);
vis[1]=1;
cnt[1]++;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(i=1;i<=n;i++)
{
if(dis[i]>dis[u]+map[u][i])
{
dis[i]=dis[u]+map[u][i];
if(vis[i]==0)
{
q.push(i);
vis[i]=1;
cnt[i]++;
if(cnt[i]>n)
{
//负环
return;
}
}
}
}
}
}
int main()
{
int i,j,a,b,c;
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
init();
for(j=1;j<=m;j++){
scanf("%d%d%d",&a,&b,&c);
if(c<map[a][b]) map[a][b]=map[b][a]=c;
}
spfa();
cout<<dis[n]<<endl;
}
return 0;
}
再来前向星优化的SPFA,另外放上一篇很好理解前向星的文章:https://blog.csdn.net/qq_34131212/article/details/76269660
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define MAX 105
#define inf 0x3f3f3f3f
using namespace std;
int head[MAX*2],vis[MAX],dis[MAX],cnt[MAX];
int n,m,tol;
struct node
{
int to;
int next;
int cost;
}go[20005];
void add (int u,int v,int c)
{
go[tol].cost=c;
go[tol].to=v;
go[tol].next=head[u];//与第tol条边同起点的下一条边的存储位置
head[u]=tol;//以i为起点的第一条边存储的位置,其实就是最后一条以tol
tol++; // 为起点的边的编号
}
void spfa()
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
int i;
for(i=2;i<=n;i++)
dis[i]=inf;
dis[1]=0;
queue<int>q;
q.push(1);
vis[1]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(i=head[u];i!=0;i=go[i].next)
{
int v=go[i].to;
int c=go[i].cost;
if(dis[v]>dis[u]+c)
{
dis[v]=dis[u]+c;
if(vis[v]==0)
{
q.push(v);
vis[v]=1;
}
}
}
}
}
int main()
{
int i,j,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0) break;
memset(head,-1,sizeof(head));
tol=1;
for(j=1;j<=m;j++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa();
cout<<dis[n]<<endl;
}
return 0;
}