题意: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的优化吧?

代码:上面给过了

题目分享F 二代目的更多相关文章

  1. 题目分享H 二代目

    题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...

  2. 题目分享E 二代目

    题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...

  3. 题目分享D 二代目

    题意:给定一个T条边的无向图,求S到E恰好经过N条边的最短路径 T≤100 N≤1000000 分析:(据说好像假期学长讲过) 首先很容易想到的是dp[i][j][k]表示从i到j经过k条边的最短路径 ...

  4. 题目分享C 二代目

    题意:一个数列是由 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6.....组成,也就是1-1,1-2,1-3......并且如果遇到多位数也要拆成数字比如1-10 ...

  5. 题目分享G 二代目

    题意:有n组数,每组包含两个数,问在每组只能取一个的前提下能组成的最长的从1开始的连续自然数有几个? 分析:刚学了差分约束系统,很容易往转换成图的方向去想 将他读入的这n组数当成边读入 很容易会得到一 ...

  6. 2019年腾讯PHP程序员面试题目分享

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...

  7. 20190924-LeetCode解数独题目分享

    解决数独 题目描述 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以 ...

  8. 题目分享X

    题意:一张票有n位数,如果这张票的前一半数字的和等于后一半数字的和(n一定是偶数),就称这张票为快乐票.有些数被擦除了,标记为’?’(’?‘的个数也是偶数),现在Monocarp 和 Bicarp 进 ...

  9. 题目分享V

    题意:现在两个人做游戏,每个人刚开始都是数字1,谁赢了就能乘以k^2,输的乘以k(k可以是任意整数,每次不一定相同)现在给你最终这两个人的得分,让你判断是否有这个可能,有可能的话Yes,否则No. 分 ...

随机推荐

  1. 学习《深入应用c++11》2

    &&   universal references(未定的引用类型),它必须被初始化,它是左值还是右值取决于它的初始化,如果&&被一个左值初始化,它就是一个左值;如果它 ...

  2. "字体图标"组件:<icon> —— 快应用组件库H-UI

     <import name="icon" src="../Common/ui/h-ui/basic/c_icon"></import> ...

  3. 了解一下mock

    1.mock简介: mock测试就是在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mo ...

  4. Linux U盘启动盘制作工具

    近期由于自己使用的ubuntu系统一直出问题,想做一下启动盘帮助恢复系统和故障检测,以前一直是用ultraiso来进行写盘的,但是发现制作了几次后,失败的机率很高,主要有以下几种情况: 1.引导有问题 ...

  5. Alpha Release Note 12/15/2015

    内容提要: ******Personal Photo Experience可供您存放所有的私人照片,系统会自动整理内容,您可以借助搜索功能快速找到所需图片,同时过滤重复图片和低质量图片,给您全新的搜索 ...

  6. 如何可视化深度学习网络中Attention层

    前言 在训练深度学习模型时,常想一窥网络结构中的attention层权重分布,观察序列输入的哪些词或者词组合是网络比较care的.在小论文中主要研究了关于词性POS对输入序列的注意力机制.同时对比实验 ...

  7. 基于 HTML5 WebGL 的高炉炼铁厂可视化系统

    前言       在当今 工业4.0 新时代的推动下,不仅迎来了 工业互联网 的发展,还开启了 5G 时代的新次元.而伴随着带宽的提升,网络信息飞速发展,能源管控上与实时预警在工业互联网中也占着举足轻 ...

  8. 详解 I/O流

    I/O流是用于处理设备之前信息传输的流,在我们今后的学习甚至是工作中,都是十分重要的. 在我们的日常生活中,也是很常见的,譬如:文件内容的合并.设备之键的文件传输,甚至是下载软件时的断点续传,都可以用 ...

  9. 5. git 过滤,让某文件夹里无法提交新添加的文件

    . gitignore  向此文件里添加文件路径就行了.如( web/core/ ) 此时git status将看不到添加的文件或文件夹了

  10. 用 Python 黄图批量鉴别审核

    前言 最近写了一款微信小程序需要用到图片审核,人工审核是不可能的人工审核的太费精力了,所以我就写了一个多线程批量识别脚本来处理,主要是调用百度AI的接口,这里我是付费了也不贵审核一条1分钱不到,再说我 ...