spfa优化 SLF LLL
2012-12-05 20:51
381 查看
2013.10.23 更新
之前写的时候不知道在想什么,整理模板时才发现写挫了,现在重发一个
SPFA 是按照 FIFO 的原则更新距离的, 没有考虑到距离标号的作用. 实现中 SPFA 有两个非常著名的优化: SLF 和 LLL.
SLF: Small Label First 策略.
实现方法是, 设队首元素为
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
,
队列中要加入节点
![](http://data.artofproblemsolving.com/images/latex/5/c/2/5c2dd944dde9e08881bef0894fe7b22a5c9c4b06.gif)
,
在
![](http://data.artofproblemsolving.com/images/latex/7/4/c/74cf276f40fc8ea054c55cbf77c0f87ac2780880.gif)
时加到队首而不是队尾, 否则和普通的 SPFA 一样加到队尾. 这可以用个优先级队列维护
LLL: Large Label Last 策略.
实现方法是, 设队列
![](http://data.artofproblemsolving.com/images/latex/c/3/1/c3156e00d3c2588c639e0d3cf6821258b05761c7.gif)
中的队首元素为
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
,
距离标号的平均值为
![](http://data.artofproblemsolving.com/images/latex/2/f/a/2fa7b8e04e7f0f96cc4212d584cd36ecf0734115.gif)
,
每次出队时, 若
![](http://data.artofproblemsolving.com/images/latex/8/b/3/8b3ae187ffe26b5bc222d3732711111a83a9fe00.gif)
,
把
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
移到队列末尾, 如此反复, 直到找到一个
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
使
![](http://data.artofproblemsolving.com/images/latex/7/5/8/758d48935f8d0ca3092e859cd01858e059df2cf7.gif)
,
将其出队.
之前写的时候不知道在想什么,整理模板时才发现写挫了,现在重发一个
SPFA 是按照 FIFO 的原则更新距离的, 没有考虑到距离标号的作用. 实现中 SPFA 有两个非常著名的优化: SLF 和 LLL.
SLF: Small Label First 策略.
实现方法是, 设队首元素为
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
,
队列中要加入节点
![](http://data.artofproblemsolving.com/images/latex/5/c/2/5c2dd944dde9e08881bef0894fe7b22a5c9c4b06.gif)
,
在
![](http://data.artofproblemsolving.com/images/latex/7/4/c/74cf276f40fc8ea054c55cbf77c0f87ac2780880.gif)
时加到队首而不是队尾, 否则和普通的 SPFA 一样加到队尾. 这可以用个优先级队列维护
LLL: Large Label Last 策略.
实现方法是, 设队列
![](http://data.artofproblemsolving.com/images/latex/c/3/1/c3156e00d3c2588c639e0d3cf6821258b05761c7.gif)
中的队首元素为
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
,
距离标号的平均值为
![](http://data.artofproblemsolving.com/images/latex/2/f/a/2fa7b8e04e7f0f96cc4212d584cd36ecf0734115.gif)
,
每次出队时, 若
![](http://data.artofproblemsolving.com/images/latex/8/b/3/8b3ae187ffe26b5bc222d3732711111a83a9fe00.gif)
,
把
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
移到队列末尾, 如此反复, 直到找到一个
![](http://data.artofproblemsolving.com/images/latex/0/4/2/042dc4512fa3d391c5170cf3aa61e6a638f84342.gif)
使
![](http://data.artofproblemsolving.com/images/latex/7/5/8/758d48935f8d0ca3092e859cd01858e059df2cf7.gif)
,
将其出队.
/** 复杂度分析: 普通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)); }
相关文章推荐
- SPFA优化:SLF,LLL,前向星
- HDU4725(KB4-P SPFA+LLL+SLF优化)
- SPFA的LLL和SLF(以及自己浪出来的PY优化,不知道有没有别人写过QAQ)
- SPFA的两种优化SLF和LLL
- 2346: [Baltic 2011]Lamp (SPFA+SLF优化)
- HDU 1535 Invitation Cards (最短路,附SLF优化SPFA)
- 算法提高 道路和航路 (SLF双向队列优化SPFA)
- POJ3255 - Roadblocks - 次短路(spfa+LLL优化)
- 【日常学习】【SPFA+SLF+LLL】codevs1021 玛丽卡题解
- 2013成都邀请赛J称号||HDU4725 The Shortest Path in Nya Graph(spfa+slf最短的优化)
- codevs 2273 扬帆远洋大战牧师妹酱(spfa+slf优化)
- [SPFA的SLF优化] Codeforces Round #257 (Div. 1) B
- hdu 1533 Going Home (zkw + spfa和slf优化)
- SPFA,SLF优化
- SPFA及SLF优化
- 单源最短路----Spfa模板 (SLF优化)
- bzoj2100 [Usaco2010 Dec]Apple Delivery(slf优化的spfa)
- SPFA及SLF优化
- spfa的SLF优化
- Codeforces Round #257 (Div. 1)B题Jzzhu and Cities(spfa+slf优化)