Title

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;
}

posted @   UncleSam_Died  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示