SPFA的SLF优化
特别鸣谢Dawn-_-cx大佬的讲解
讲解都在代码里了:
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
struct Edge{//链式前向星存图
int v,w,next;
}tu[100010];
int head[100010],dis[100010],vis[100010],ce;//dis数组存储到点的距离,vis数组存储这个点是否走过(走过值为1,没走过值为0)
inline void adde(int u,int v,int w){//链式前向星加边
tu[++ce].v=v,tu[ce].w=w,tu[ce].next=head[u];
head[u]=ce;
}
inline void SPFA(int x){//SFPA,求点X到每个点的最短距离
deque<int>q;//定义一个双向队列
for(int i=1;i<=n;i++){//初始化dis数组和vis数组 (如果不需要多次查询的话可以不用这一步),也可以把dis和vis开成二维数组,用空间换时间(好像有点亏)
dis[i]=inf;
vis[i]=0;
}
q.push_back(x);//把x加入队列中
dis[x]=0;//x点到自己的距离为0
vis[x]=1;//把x点标记为走过
while(!q.empty()){//如果队列不为空,说明还有点没有遍历过
int u=q.front();//获取队首值,即u
q.pop_front();//将u弹出
vis[u]=0;//先将u的vis值赋为0
for(int i=head[u];i;i=tu[i].next){//用链式前向星一次遍历每一个和u相连的点
int v=tu[i].v,w=tu[i].w;//获取相连的点的编号和连边权值
if(dis[v]>dis[u]+w){//三角形不等式,即找到更短的路
dis[v]=dis[u]+w;//更新最小值
if(!vis[v]){//如果这个点没有走过
vis[v]=true;//标记为走过
if(q.empty()||dis[v]>dis[q.front()]) q.push_back(v);//如果v的dis值小于队首的dis值,就把v放队首
else q.push_front(v);//否则放队尾
}
}
}
}
for(int i=1;i<=n;i++){//循环输出x到每一个点的最短路,如果不能(dis[i]的值仍为inf(未更新))到达输出Impossible
if(dis[i]==inf) cout<<"Impossible ";
else cout<<dis[i]<<" ";
}
cout<<endl;
}
int main(){
cin>>n>>m;//输入,n个点,m条边
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
adde(u,v,w);//在u和v之间连一条权值为w的有向边
adde(v,u,w);
}
int x;//输入要找的点X
cin>>x;
SPFA(x);//找x到每个点的最短路
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!