以前一直写的Dijkstra,快考试了看了眼SPFA,感觉两个代码几乎一模一样?
Dijkstra
for(int i=1;i<=n;i++)
{
dis[i]=INF;
}
dis[s]=0;
//赋初值
q.push((node){0,s});
while(!q.empty())
//堆为空即为所有点都更新
{
node x=q.top();
q.pop();
int u=x.now;
//记录堆顶(堆内最小的边)并将其弹出
if(vis[u]) continue;
//没有遍历过才需要遍历
vis[u]=1;
for(int i=head[u];i;i=e[i].next)
//搜索堆顶所有连边
{
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
//松弛操作
q.push((node){dis[v],v});
//把新遍历到的点加入堆中
}
}
}
SPFA
for(int i=1; i<=n; i++)
{
dis[i]=inf;
//赋初值
}
int u,v;
q.push(s);
dis[s]=0;
//将起点的值负为0
vis[s]=1;//这句话可加可不加,因为循环的时候vis[s]又会被赋为0
while(!q.empty())
//当队列里没有元素的时候,那就已经更新了所有的单源最短路径
{
u=q.front();
//将队手节点记录并弹出队首节点
q.pop();
vis[u]=0;
for(int i=head[u];i;i=h[i].next)
//寻找与u相连的边
{
v=h[i].to;
if(dis[v]>dis[u]+h[i].w)
{
dis[v]=dis[u]+h[i].w;
//松弛操作,和floyd比较相似
if(!vis[v])
{
//已经在队列里的点就不用再进入了
vis[v]=1;
q.push(v);
}
}
}
}
感觉就是判vis换了个地方,然后Dijkstra有个优先队列优化?