spfa优化
的优化都是基于 的,我们通常使用 优化,代码简单,优化效果最好,详情可见参考这里,例题可以参考这里
1. 优化(入队优化)
Large Label Last 优化
:思路就是将 更大的点放入队尾,将 更小的点放入队头,优先使用 更小的点进行松弛操作。
void spfa(int head)
{
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
dist[head] = 0;
deque<int> q;
q.push_front(head);
st[head] = true;
while(q.size())
{
int cur = q.front();
q.pop_front();
st[cur] = false;
for(int i = h[cur]; i != -1; i = ne[i])
{
int j = e[i];
if(dist[j] > dist[cur] + w[i])
{
dist[j] = dist[cur] + w[i];
if(!st[j])
{
/*============== LLL 优化 ==============*/
if(q.empty() || dist[j] > dist[q.front()])
q.push_back(j);
else q.push_front(j);
/*======================================*/
st[j] = true;
}
}
}
}
}
2. 优化(出队优化)
Small Label First 优化
:优先让 更小的节点出队来进行松弛操作,不过这个“小”并不好把握,总不能遍历一遍队列找这个小的 把。因此,这里的“小”是平均意义上的小,即小于等于队列中所有元素的平均值,因此我们要维护队列元素个数 (不用q.size()
,调用函数可能更慢)和队列中的元素和 ,通过 while
来进行判断,不过由于优化逻辑中有个 while
,其优化效果可能很玄?
void spfa(int head)
{
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
dist[head] = 0;
deque<int> q;
q.push_front(head);
st[head] = true;
/*================================*/
int sum = dist[head], cnt = 1;
/*================================*/
while(q.size())
{
int cur = q.front();
/*============================*/
while(dist[cur] * cnt > sum)
{
q.push_front();
q.push_back(cur);
cur = q.front();
}
/*============================*/
q.pop_front();
st[cur] = false;
/*============================*/
cnt -- , sum -= dist[cur];
/*============================*/
for(int i = h[cur]; i != -1; i = ne[i])
{
int j = e[i];
if(dist[j] > dist[cur] + w[i])
{
dist[j] = dist[cur] + w[i];
if(!st[j])
{
q.push_back(j);
/*============================*/
cnt ++ , sum += dist[j];
/*============================*/
st[j] = true;
}
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)