SPFA和dijkstra优化

本文深入探讨了SPFA和Dijkstra两种单源最短路径算法的特点与优化技巧。SPFA算法虽然时间复杂度不确定,但能处理负权边,通过SLFSLFSLF和LLLLLLLLL优化提升效率;而Dijkstra算法适用于无负权边的情况,具有O((n+m)log2n)的时间复杂度,通过堆优化进一步提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SPFA

  • 单源最短路,好哇

  • 时间复杂度玄

  • 无畏负权边,容易被卡负环

  • 好打好理解

  • SLFSLFSLF优化:如果当前要入队一个点iii,如果dis[i]&lt;dis[que[head]]dis[i] &lt; dis[que[head]]dis[i]<dis[que[head]] (比队首要优)就放入队首,否则就放入队尾

  • LLLLLLLLL优化:如果当前的出队的数(que[head]que[head]que[head]),他的disdisdis大于队列中所有disdisdis的平均值,那么就把que[head]que[head]que[head]入队尾,然后continuecontinuecontinue

  • 可以用STLSTLSTLdequedequedeque来实现SLFSLFSLFLLLLLLLLL乱搞就行

inline void spfa()
{
	ll z=0,length=1;
	while (que.size())que.pop_front();
	memset(bz,1,sizeof(bz));
	memset(dis,100,sizeof(dis));
	que.push_front(S),dis[S]=bz[S]=0;
	while (que.size())
	{
		ll now=que.front();
		if (length*dis[now]>z)
		{//LLL优化
			que.pop_front(),que.push_back(now);
			continue;
		}
		--length,z-=dis[now];
		que.pop_front(),bz[now]=1;
		rep(i,now)
		{
			if (dis[now]+len[i]<dis[tov[i]])
			{
				dis[tov[i]]=dis[now]+len[i];
				if (bz[tov[i]])
				{
					bz[tov[i]]=0,z+=dis[tov[i]],++length;
					if (que.empty() || dis[que.front()]<dis[tov[i]])que.push_back(tov[i]);//比队头劣则入队尾
					else que.push_front(tov[i]);//反之则入队头
				}
			}
		}
	}
}

dijkstra

  • 单源最短路,更好

  • 时间复杂度O((n+m)log2n)O((n+m)log_2n)O((n+m)log2n),很多题目一般可以看成O(nlog2n)O(nlog_2n)O(nlog2n)乘上个333左右的常数

  • 只要没有负权边就强大通用

  • 优化用STLSTLSTLpriorityprioritypriority_queuequeuequeue就行了

  • 堆优化完比SPFASPFASPFA还短,以后都不打SPFA.jpg

struct node
{
	ll x,y;
	bool operator <(const node &a)const
	{
		return a.y<y;
	}
};
priority_queue<node>que;

inline void dijkstra()
{
	while (!que.empty())que.pop();
	memset(dis,100,sizeof(dis));
	memset(bz,0,sizeof(bz));
	que.push((node){S,dis[S]=0});
	while (!que.empty())
	{
		node now=que.top();que.pop();
		if (bz[now.x])continue;bz[now.x]=1;
		rep(i,now.x)
		{
			if (dis[now.x]+len[i]<dis[tov[i]])
			{
				dis[tov[i]]=dis[now.x]+len[i];
				if (!bz[tov[i]])que.push((node){tov[i],dis[tov[i]]});
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值