题意:T个点R种双向边,P种单向边,求点S到每个点的最短距离

分析:(这再看不出来是spfa就该**了)

首先,这题能否用spfa就看他是否有负环呗,显然,双向边的权值非负,单向边还有个啥政策,总之显然是没有负环了

那么直接跑裸的spfa

没想到竟然t了

难不成spfa还有优化?

我带着怀疑的心情上了百度,艹还真有

  SLF优化:

  SLF优化,即 Small Label First  策略,使用 双端队列 进行优化。

  一般可以优化15%~20%,在竞赛中比较常用。

  设从 u 扩展出了 v ,队列中队首元素为 k ,若 dis[ v ] < dis[ k ] ,则将 v 插入队首,否则插入队尾。

  注:队列为空时直接插入队尾。

妙啊,我加上这个优化直接就过了,代码也很好写

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std; const int maxm=2e5+;
const int maxn=3e4+;
const int inf=0x3f3f3f3f; struct Node
{
int to,next,val;
}e[maxm];
int head[maxn];
int dis[maxn];
bool vis[maxn];
int cnt; void add(int x,int y,int z)
{
e[++cnt].to=y;
e[cnt].val=z;
e[cnt].next=head[x];
head[x]=cnt;
} int read()
{
char ch=getchar();int ans=,p=;
while(ch>''||ch<'')
{
if(ch=='-') p=-;
ch=getchar();
}
while(ch<=''&&ch>='')
{
ans=(ans<<)+(ans<<)+ch-'';
ch=getchar();
}
return ans*p;
} void spfa(int x)
{
memset(dis,0x3f,sizeof(dis));
deque<int> q;q.push_back(x),dis[x]=;
while(!q.empty())
{
int now=q.front();q.pop_front();
vis[now]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[now]+e[i].val)
{
dis[v]=dis[now]+e[i].val;
if(!vis[v])
{
vis[v]=;
if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);
else q.push_back(v);
}
}
}
}
} int main()
{
int t,r,p,s,x,y,z;
t=read(),r=read(),p=read(),s=read();
while(r--)
{
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
while(p--)
{
x=read(),y=read(),z=read();
add(x,y,z);
}
spfa(s);
for(int i=;i<=t;i++)
{
if(dis[i]==inf) printf("NO PATH\n");
else printf("%d\n",dis[i]);
}
return ;
}

然后我接着往下看,还有一个优化

  

  LLL优化:

  LLL优化,即 Large Label Last  策略,使用 双端队列 进行优化。

  一般用SLF+LLL可以优化50%左右,但是在竞赛中并不常用LLL优化。

  设队首元素为 k ,每次松弛时进行判断,队列中所有 dis 值的平均值为 x 。

  若 dist[ k ] > x ,则将 k 插入到队尾,查找下一元素,直到找到某一个 k 使得 dis[ k ] <= x ,则将 k 出队进行松弛操作。

我也给他写出来了

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std; #define ll long long const int maxm=2e5+;
const int maxn=3e4+;
const int inf=0x3f3f3f3f; struct Node
{
int to,next,val;
}e[maxm];
int head[maxn];
int dis[maxn];
bool vis[maxn];
int cnt; void add(int x,int y,int z)
{
e[++cnt].to=y;
e[cnt].val=z;
e[cnt].next=head[x];
head[x]=cnt;
} int read()
{
char ch=getchar();int ans=,p=;
while(ch>''||ch<'')
{
if(ch=='-') p=-;
ch=getchar();
}
while(ch<=''&&ch>='')
{
ans=(ans<<)+(ans<<)+ch-'';
ch=getchar();
}
return ans*p;
} void spfa(int x)
{
int num=;ll sum=;
memset(dis,0x3f,sizeof(dis));
deque<int> q;q.push_back(x),dis[x]=;
while(!q.empty())
{
int now=q.front();q.pop_front();
num--,sum-=dis[now];
while(num&&dis[now]>sum/num)
{
q.push_back(now);
now=q.front();
q.pop_front();
}
vis[now]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(dis[v]>dis[now]+e[i].val)
{
dis[v]=dis[now]+e[i].val;
if(!vis[v])
{
vis[v]=;
if(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);
else q.push_back(v);
num++,sum+=dis[v];
}
}
}
}
} int main()
{
int t,r,p,s,x,y,z;
t=read(),r=read(),p=read(),s=read();
while(r--)
{
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
while(p--)
{
x=read(),y=read(),z=read();
add(x,y,z);
}
spfa(s);
for(int i=;i<=t;i++)
{
if(dis[i]==inf) printf("NO PATH\n");
else printf("%d\n",dis[i]);
}
return ;
}

令我没想到的是,这俩加起来竟然又t了

也可能是我写的不对,也有可能这个优化被卡了

总之以后我写spfa一定会带上SLF优化的,

这个题大概老姚是想让我们了解一下spfa的优化吧?

代码:上面给过了

最新文章

  1. git取消跟踪文件
  2. HTML是什么
  3. 【NOIP2015】推销员
  4. JavaScript高级程序设计之基本包装类型
  5. 使用SqlTransaction回滚事务
  6. Android小项目之十一 应用程序的主界面
  7. 备份了一个nginx的虚拟主机配置文件报错
  8. jQuery 遍历同胞(siblings)
  9. hdu 3720 Arranging Your Team 枚举
  10. Java 银行家算法
  11. 关于autofac的一些具体的用法
  12. 第八节,配置分布式TensorFlow
  13. 简单整理关于C#和Java的区别
  14. Node.js中文乱码解决方法
  15. spring继承Rabbitmq client-----------------------待研究
  16. mysql执行计划查看工具explain
  17. springsecurity基于数据库验证用户
  18. POJ 1061 青蛙的约会(拓展欧几里得算法求解模线性方程组详解)
  19. 当activity改变时,我们如何处理它
  20. php理解变量的作用域

热门文章

  1. 7.1 java 类、(成员)变量、(成员)方法
  2. HAproxy shell脚本安装
  3. 数据结构和算法(Golang实现)(1)简单入门Golang-前言
  4. CVE-2019-17671:wrodpress 未授权访问漏洞-复现
  5. Linux终端命令格式
  6. B - Fadi and LCM CodeForces - 1285C 质因子
  7. vue2.x学习笔记(一)
  8. HuggingFace-transformers系列的介绍以及在下游任务中的使用
  9. swoole--服务平滑重启
  10. iconv 参数详解