/*
它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,
其中k为所有顶点进队的平均次数,可以证明k一般小于等于2,
可以处理负边,但无法处理带负环的图(负环和负边不是一个概念)
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1000;
struct node
{
int to;
int w;
int next;
}edge[N*2];
int head[N];
int cnt;
int dist[N];//到第i点的权值
bool vis[N];//元素是否在队内
int n,m;
void add(int u,int v,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
void init()
{
memset(dist,0x3f3f3f3f3f,sizeof(dist));//距离初始化到无穷
dist[1]=0;
}
void spfa(int x)
{
queue<int>q;
init();
q.push(x);//先将x入队
vis[x]=1;
while(!q.empty())
{
int tmp=q.front();
q.pop();
vis[tmp]=0;//出队 vis置0
for(int i=head[tmp];i;i=edge[i].next)
{
int to=edge[i].to;
//如果能缩进距离就更新
if(dist[to]>dist[tmp]+edge[i].w)
{
dist[to]=dist[tmp]+edge[i].w;
//如果不在队中就入队
if(!vis[to])
{
vis[to]=1;
q.push(to);
}
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,w;
cin>>a>>b>>w;
add(a,b,w);
add(b,a,w);//双向
}
spfa(1);
for(int i=1;i<=n;i++)
{
cout<<dist[i]<<endl;
}
return 0;
}
基于链式前向星的SPAF算法(最短路径)
于 2023-04-12 15:53:06 首次发布