poj3539 Elevator——同余类bfs
题目:http://poj.org/problem?id=3539
题目大意是给定 a, b, c,求 1~h 内有多少个数可以被 a, b, c 通过加减法组成;
这是今天刚讲的神奇的——同余类 bfs 问题!
大概就是选定一个模数,就选最小的(常数可能会比较小?),不妨令作 a,构建一系列点,组成 mod a 剩余系;
然后我们要找到每个点的最小可达数,然后它加上若干个 a 就都是可达的;
对于一个点 x,它可以转移到 (x + b) % b,代价是 b ;c 同理;
从起点开始 bfs,对于本题来说就是1%a,且 dis[1%a] = 1(层数),求出 dis[] 数组,就是每个点的最小可达数;
计算答案就是对于每个余数(点),看看在1~h 中有多少个它加若干 a 可达的数,也就是 (h - dis[x]) / a + 1;
不过其实不 bfs 也可以,反正就是求最短路;
注意 dis 是 long long 哟~
代码如下:
dijkstra:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
int const maxn=1e5+;
ll h,ans,dis[maxn];
int a,b,c,hd[maxn],ct;
priority_queue<pair<ll,int> >q;
bool vis[maxn];
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxn<<];
void add(int x,int y,int z){ed[++ct]=N(y,hd[x],z); hd[x]=ct;}
void dijkstra()
{
memset(dis,0x3f,sizeof dis);
dis[%a]=; q.push(make_pair(-,%a));
while(q.size())
{
int x=q.top().second; q.pop();
if(vis[x])continue;
vis[x]=;
for(int i=hd[x];i;i=ed[i].nxt)
{
int u=ed[i].to;
if(dis[u]>dis[x]+ed[i].w)
{
dis[u]=dis[x]+ed[i].w;
q.push(make_pair(-dis[u],u));
}
}
}
}
int main()
{
scanf("%lld%d%d%d",&h,&a,&b,&c);
if(a>b)swap(a,b); if(a>c)swap(a,c);
for(int i=;i<a;i++)
{
add(i,(i+b)%a,b);
add(i,(i+c)%a,c);
}
dijkstra();
for(int i=;i<a;i++)
{
if(dis[i]>h)continue;//!
ans+=(ll)(h-dis[i])/a+;
}
printf("%lld\n",ans);
return ;
}
dijkstra
spfa:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
int const maxn=1e5+;
ll h,ans,dis[maxn];
int a,b,c,hd[maxn],ct;
queue<int>q;
bool vis[maxn];
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxn<<];
void add(int x,int y,int z){ed[++ct]=N(y,hd[x],z); hd[x]=ct;}
void spfa()
{
memset(dis,0x3f,sizeof dis);
dis[%a]=; q.push(%a); vis[%a]=;
while(q.size())
{
int x=q.front(); q.pop(); vis[x]=;
for(int i=hd[x];i;i=ed[i].nxt)
{
int u=ed[i].to;
if(dis[u]>dis[x]+ed[i].w)
{
dis[u]=dis[x]+ed[i].w;
if(!vis[u])vis[u]=,q.push(u);
}
}
}
}
int main()
{
scanf("%lld%d%d%d",&h,&a,&b,&c);
if(a>b)swap(a,b); if(a>c)swap(a,c);
for(int i=;i<a;i++)
{
add(i,(i+b)%a,b);
add(i,(i+c)%a,c);
}
spfa();
for(int i=;i<a;i++)
{
if(dis[i]>h)continue;//!
ans+=(ll)(h-dis[i])/a+;
}
printf("%lld\n",ans);
return ;
}
spfa
bfs:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
int const maxn=1e5+;
ll h,ans;
ll a,b,c,dis[maxn];//ll
queue<int>q;
bool vis[maxn];
void bfs()
{
memset(dis,0x3f,sizeof dis);
dis[%a]=; q.push(%a); vis[%a]=;
while(q.size())
{
int x=q.front(),u; q.pop(); vis[x]=;
if(dis[u=(x+b)%a]>dis[x]+b)
{
dis[u]=dis[x]+b;
if(!vis[u])/*vis[u]=1,*/q.push(u);
}
if(dis[u=(x+c)%a]>dis[x]+c)
{
dis[u]=dis[x]+c;
if(!vis[u])/*vis[u]=1,*/q.push(u);
}
}
}
int main()
{
scanf("%lld%lld%lld%lld",&h,&a,&b,&c);
if(a>b)swap(a,b); if(a>c)swap(a,c);
bfs();
for(int i=;i<a;i++)
{
if(dis[i]>h)continue;//!
ans+=(h-dis[i])/a+;
}
printf("%lld\n",ans);
return ;
}
poj3539 Elevator——同余类bfs的更多相关文章
- [poj 3539] Elevator (同余类bfs)
Description Edward works as an engineer for Non-trivial Elevators: Engineering, Research and Constru ...
- poj 3539 Elevator——同余类bfs
题目:http://poj.org/problem?id=3539 考虑把层数分为模a剩余系.同类内可通过+若干个a走到. 不同类之间需要通过+b.+c来走到. 需要求出每一类中最小的能走到的.即最短 ...
- 同余类BFS的一些瞎吹
同余类BFS的题,是个OIer基本上都会见过一些,最好的例子就是NOIP 2018 day1 T2---货币系统 虽然这题其实是什么背包就能解决的题目,但数据一变大,出题人坏一点,就没了.... 同 ...
- POJ 3539 Elevator(同余类BFS)
题意 有一部电梯,最初停在1层. 电梯有4个按键,上升a,b,c层,回到一层. 求从一层出发.能到达1~h的哪些楼层. (h<=1018,a,b,c<=105) 题解 这种h能大的图论,一 ...
- BZOJ2118: 墨墨的等式(同余类BFS)(数学转为图论题)
2118: 墨墨的等式 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2944 Solved: 1206[Submit][Status][Discu ...
- POJ3539 Elevator
Time Limit: 4000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Description Edward wor ...
- Luogu4156 WC2016 论战捆竹竿 KMP、同余类最短路、背包、单调队列
传送门 豪华升级版同余类最短路-- 官方题解 主要写几个小trick: \(1.O(nm)\)实现同余类最短路: 设某一条边长度为\(x\),那么我们选择一个点,在同余类上不断跳\(x\),可以形成一 ...
- NOIP 2017 小凯的疑惑(同余类)
题意 给出两个互质的数a,b问最大的不能被xa+yb(x,y>=0)表示的数.(a,b<=109) 题解 NOIPday1T1一道数论题,不知埋葬了多少人的梦想. 用同余类去解释. 我们依 ...
- BZOJ2118 墨墨的等式[同余类最短路]
声明:关于这题的$O(mn)$尚且未深入理解,虽然之前有跟这位神仙聊过做法但并没太懂.. $O(mn\log m)$同余最短路做法: 首先不妨抽出最小的$a_i=m$,那么剩余的$a$如果可以表示出$ ...
随机推荐
- 02C++基本语法
基本语法 2.1.1单行注释 // 2.1.2多行注释 /* * */ 2.1.3标识符 C++ 标识符是用来标识变量.函数.类.模块,或任何其他用户自定义项目的名称.一个标识符以字母 A-Z 或 a ...
- relax 网站
1. Calm 网站链接:http://www.calm.com/ 这个网站就像它的名字一样“平和”,网站的设计是通过自然图片(阳光下的暖流.流淌的消息等)与缓缓的音乐相结合,帮你在短时间内即可放松下 ...
- DH密钥交换算法
DH密钥交换算法:DH的全称为Diffie-Hellman ,该算法可以在需要安全传输的前提下,确定双方的对称密钥,该算法的核心在于双方的私钥没有进入网络传输流程,根据对方的公钥和己方的私钥,可以计算 ...
- Luogu P4549 裴蜀定理 / Min
思路 题目已经给出了正解.我们只需要将裴蜀定理推广到若干数的线性组合就可以做这道题了 要注意的是需要在输入的时候取一个绝对值.因为可能会有负数存在.我之前也写过裴蜀定理的证明,要看的话点这里 吐槽 第 ...
- linux top-显示或管理执行中的程序
推荐:更多linux 性能监测与优化 关注:linux命令大全 top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具.通过top命令所提供的互动式界面, ...
- python下载网络文件
python下载网络文件 制作人:全心全意 下载图片 #!/usr/bin/python #-*- coding: utf-8 -*- import requests url = "http ...
- illuminate/routing 源码分析之注册路由
我们知道,在 Laravel 世界里,外界传进来一个 Request 时,会被 Kernel 处理并返回给外界一个 Response.Kernel 在处理 Request 时,会调用 illumina ...
- shoppping collection
personal shopping collections shop Table of Contents 1. phone network 2. band share 3. Motorcycle He ...
- CKplayer:视频推荐和分享插件设置
如果想去掉播放结束后显示精彩视频推荐的插件,可以打开ckplayer.js和ckplayer.xml,找到以下代码,然后注释掉即可: control_rel: 'related.swf,ckplaye ...
- Regular Number 字符串匹配算法 Shift_and
Using regular expression to define a numeric string is a very common thing. Generally, use the shape ...