spfa优化 SLF LLL

简介:

2013.10.23 更新

之前写的时候不知道在想什么,整理模板时才发现写挫了,现在重发一个


SPFA 是按照 FIFO 的原则更新距离的, 没有考虑到距离标号的作用. 实现中 SPFA 有两个非常著名的优化: SLF 和 LLL.

  SLF: Small Label First 策略.
  实现方法是, 设队首元素为 i, 队列中要加入节点 j, 在 d_j \le d_i 时加到队首而不是队尾, 否则和普通的 SPFA 一样加到队尾. 这可以用个优先级队列维护

  LLL: Large Label Last 策略. 
  实现方法是, 设队列 Q 中的队首元素为 i, 距离标号的平均值为 \overline d = \frac {\sum_{j \in Q} d_j }{\left| Q \right|}, 每次出队时, 若 d_i > \overline d, 把 i 移到队列末尾, 如此反复, 直到找到一个 i 使 d_i \le \overline d, 将其出队.

 

/**
    复杂度分析:
        普通SPFA km kmax=n 不适合稠密图 一般为2
        优先级队列  加入节点复杂度logn 节点数太多时适得其反,对于特殊数据速度略小于普通spfa
                     对于随机图效果很好
        手动模拟SLF,LLL 复杂度低于优先级队列,最坏情况与普通SPFA持平

*/

#define Maxn 100010//最大点数
#define Maxm 400010//最大边数,无向图要建双向边
int w[Maxm],u[Maxm],next[Maxm],cnt;
int first[Maxn],havein[Maxn];//havin为入队次数
long long d[Maxn];//距离
int n;
bool in[Maxn];//队中标志
inline void add(int vn,int un,int wn){//邻接表存储
    u[cnt]=un;w[cnt]=wn;next[cnt]=first[vn];first[vn]=cnt++;
}
struct node{
    int v,dd;
    node(int &a):v(a),dd(d[a]){};
    bool operator< (const node& a)const{
        return dd>a.dd;
    }
};
priority_queue<node> q; //利用优先级队列SLF和LLL
bool spfa(int s){
    int i,now,ne,t;
    memset(in,0,sizeof(in));
    memset(havein,0,sizeof(havein));
    for(i=0;i<n;i++)d[i]=INF; //memset(d,0x3f,sizeof(d));
    d[s]=0;in[s]=1;q.push(s);
    while(!q.empty()){
        now=q.top().v;q.pop();
        if(!in[now])continue;
        in[now]=0;
        for(i=first[now];~i;i=next[i]){
            ne=u[i];
            if(d[ne]<=(t=d[now]+w[i]))continue;
            d[ne]=t; in[ne]=1; q.push(ne);
            if(++havein[ne]>n)return 0;//判断有无负环
        }
    }
    return 1;//返回1为正常,0为有负环
}
#define M 200000  //手动模拟
int q[M];
bool spfa(int s){
    int i,now,ne,t;
    memset(in,0,sizeof(in));
    memset(havein,0,sizeof(havein));
    memset(d,0x3f,sizeof(d));
    int l,r,len;l=r=len=0;
    long long sum=0;
    d[s]=0;in[s]=havein[s]=1;
    q[r++]=s;len++;
    while(l!=r){
        now=q[l++];
        if(l==M)l=0;
        if(d[now]*len>sum){//LLL
            q[r++]=now;
            if(r==M)r=0;
            continue;
        }
        len--; sum-=d[now]; in[now]=0;
        for(i=first[now];~i;i=Next[i]){
            ne=u[i];
            if(d[ne]<=(t=d[now]+w[i]))continue;
            d[ne]=t;
            if(in[ne])continue;
            in[ne]=1;
            if(t<=d[q[l]]){ //SLF
                if(--l<0)l=M-1;
                q[l]=ne;
            }
            else{
                q[r++]=ne;
                if(r==M)r=0;
            }
            len++; sum+=t;
            if(++havein[ne]>n)return 0;
        }
    }
    return 1;//返回1为正常,0为有负环
}
void init()//边初始化
{
    cnt=0;
    memset(first,-1,sizeof(first));
}


目录
相关文章
|
机器学习/深度学习 人工智能 搜索推荐
人工智能发音评估(Artificial Intelligence Pronunciation Scoring, AI-PS)
人工智能发音评估(Artificial Intelligence Pronunciation Scoring, AI-PS)
1269 2
|
12月前
|
人工智能
巧妙构建歌词结构:写歌词的技巧和方法之关键,妙笔生词AI智能写歌词软件
在音乐世界里,歌词是灵魂的载体,构建其结构至关重要。优秀的歌词需有引人入胜的开头、条理清晰且富变化的主体,以及深刻难忘的结尾。《妙笔生词智能写歌词软件》提供多种功能,帮助创作者克服结构难题,激发灵感,助你写出打动人心的歌词,开启音乐创作的新篇章。
|
9月前
|
存储 缓存 运维
“网”罗天下,一键搞定:netsh命令的花式玩法与超实用攻略
`netsh`是Windows系统中强大的网络配置和管理工具,支持本地或远程修改网络设置。常用功能包括:显示和配置网络接口、无线网络管理、防火墙规则设置、网络配置备份与还原、远程管理等。通过`netsh`命令,用户可以轻松管理IP地址、启用/禁用网络接口、添加或删除无线网络配置文件、配置防火墙规则,并进行网络故障排查。掌握这些命令能大幅提升网络管理和维护效率。
876 11
|
12月前
|
人工智能
写歌词的技巧和方法入门指南:点亮音乐创作梦想,妙笔生词智能写歌词软件
对于怀揣音乐创作梦想的人来说,写歌词是关键一步。本文介绍写歌词的技巧和方法,推荐使用《妙笔生词智能写歌词软件》辅助创作,涵盖 AI 智能写词、押韵优化等功能。积累灵感素材,确定主题,构建歌词结构,使用简洁而富有感染力的语言,让创作更轻松。
|
11月前
|
弹性计算 并行计算 双11
阿里云服务器多少钱一年?2024年11月最新价格表,爆款配置清单
2024年双十一期间,阿里云推出多款优惠云服务器配置。最便宜的轻量应用服务器2核2G、3M带宽、50GB ESSD云盘,仅需36元一年;ECS云服务器2核2G、3M带宽、40GB ESSD Entry云盘,99元一年;ECS u1实例2核4G、5M带宽、80GB ESSD Entry盘,199元一年。更多配置详见官网。
980 0
|
机器学习/深度学习 自然语言处理 算法
长序列中Transformers的高级注意力机制总结
Transformers在处理长序列时面临注意力分散和噪音问题,随着序列增长,注意力得分被稀释,影响相关上下文表示。文章探讨了序列长度如何影响注意力机制,并提出了多种解决方案:局部敏感哈希减少计算需求,低秩注意力通过矩阵分解简化计算,分段注意力将输入分割处理,层次化注意力逐级应用注意力,递归记忆增强上下文保持,带有路由的注意力机制动态调整信息流,以及相对位置编码改进序列理解。这些方法旨在提高Transformer在长序列任务中的效率和性能。
788 3
|
数据中心 网络架构
网络中不同类型网线的特点与应用
【8月更文挑战第24天】
712 0
Altium Designer中编译原理图之后出现 off grid at..... 的解决方法
Altium Designer中编译原理图之后出现 off grid at..... 的解决方法
1066 0
|
Java 编译器 Go
QT软件开发:基于libVLC内核设计视频播放器
QT软件开发:基于libVLC内核设计视频播放器
1251 0
QT软件开发:基于libVLC内核设计视频播放器
|
前端开发 JavaScript Java
【软件设计师备考 专题 】如何选择合适的程序设计语言
【软件设计师备考 专题 】如何选择合适的程序设计语言
425 0