LINK:雅加达的摩天楼

容易想到设\(f_{i,j}\)表示第i个\(doge\)在第j层楼的最小步数.

转移显然是bfs.值得一提的是把初始某层的\(doge\)加入队列 然后转移边权全为1不需要 双端队列的bfs.

复杂度为状态数量\(n\cdot m\)

可以发现 可能有两个\(doge\)跳在同一层楼 且 跳跃能力相同 显然其中一个一定没用 可以进行一些小优化 将状态改写成\(f_{i,j}\)到达第i层楼跳跃能力为j的最小步数.

复杂度\(n\cdot sqrt n\) 证明和另外一种解法如下:

观察\(n\)为\(30000\)容易想到利用分块来解决问题.

把跳跃能力和\(B=\sqrt n\)做比较,可以当跳跃能力\(p_i<=B\)时 将这种能力在图中的边连接 边数最坏为\(n\cdot B\)

当\(p_i>B\)时 最坏可跳位置只有\(\frac{n}{B}\)个 此时边数为\(m\cdot \frac{n}{B}\)即\(m\cdot B\)

可以得到边数的数量级为\(n\cdot B\) 也就是到达某个点的状态\(i,j\)跳跃能力为j这样的二元组只有\(n\cdot B\)个.

设\(f_{i,j}\)表示到达第i层楼此时跳跃能力为j的最小步数。

直接bfs即可 复杂度为状态数\(n\cdot B\)

code
//#include<bits/stdc++.h>
#include<iostream>
#include<queue>
#include<iomanip>
#include<cctype>
#include<cstdio>
#include<deque>
#include<utility>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)>(y)?(y):(x))
#define INF 1000000000
#define ll long long
#define db double
#define mod 1000000007
#define pii pair<ll,ll>
#define mk make_pair
#define us unsigned
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
int x=0,f=1;char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=30010;
int n,m,ans=-1,st,en;
int vis[MAXN];
vector<int>g[MAXN];
bitset<MAXN>w[MAXN];
struct wy
{
int x,p;
int v;
};
queue<wy> q;
inline void insert(int x,int c,int v)
{
if(!w[x][c]){q.push((wy){x,c,v});w[x][c]=1;}
if(vis[x])return;
for(us int i=0;i<g[x].size();++i)
{
int tn=g[x][i];
if(!w[x][tn])
{
q.push((wy){x,tn,v});
w[x][tn]=1;
}
}
vis[x]=1;
}
inline void bfs()
{
while(q.size())
{
wy a=q.front();q.pop();
if(a.x==en){ans=a.v;return;}
if(a.x-a.p>=0)insert(a.x-a.p,a.p,a.v+1);
if(a.x+a.p<n)insert(a.x+a.p,a.p,a.v+1);
}
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(int i=1;i<=m;++i)
{
int x,p;
x=read();p=read();
if(i==1)st=x;
if(i==2)en=x;
g[x].push_back(p);
}
vis[st]=1;
for(us int i=0;i<g[st].size();++i)
{
int tn=g[st][i];
if(!w[st][tn])
{
q.push((wy){st,tn,0});
w[st][tn]=1;
}
}
bfs();
printf("%d\n",ans);
return 0;
}

luogu P3645 [APIO2015]雅加达的摩天楼 分块 根号分治的更多相关文章

  1. luogu P3645 [APIO2015]雅加达的摩天楼

    luogu 暴力? 暴力! 这个题有点像最短路,所以设\(f_{i,j}\)表示在\(i\)号楼,当前\(doge\)跳跃能力为\(j\)的最短步数,转移要么跳一步到\(f_{i+j,j}\)和\(f ...

  2. 【题解】P3645 [APIO2015]雅加达的摩天楼(分层图最短路)

    [题解]P3645 [APIO2015]雅加达的摩天楼(分层图最短路) 感觉分层图是个很灵活的东西 直接连边的话,边数是\(O(n^2)\)的过不去 然而我们有一个优化的办法,可以建一个新图\(G=( ...

  3. 洛谷P3645 [APIO2015]雅加达的摩天楼(最短路+分块)

    传送门 这最短路的建图怎么和网络流一样玄学…… 一个最朴素的想法是从每一个点向它能到达的所有点连边,边权为跳的次数,然后跑最短路(然而边数是$O(n^2)$除非自创复杂度比spfa和dijkstra还 ...

  4. 洛谷P3645 [APIO2015]雅加达的摩天楼

    题目描述 印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N − 1.除了这 NN 座摩天楼外,雅加达市没有其他摩天楼. 有 M 只叫做 “doge” 的神 ...

  5. BZOJ 4070 [Apio2015]雅加达的摩天楼 ——分块 SPFA

    挺有趣的分块的题目. 直接暴力建边SPFA貌似是$O(nm)$的. 然后考虑分块,$\sqrt n$一下用虚拟节点辅助连边, 以上的直接暴力连边即可. 然后卡卡时间,卡卡空间. 终于在UOJ上T掉辣. ...

  6. [APIO2015] 雅加达的摩天楼 (分块,最短路)

    题目链接 Solution 分块+\(Dijkstra\). 难点在于建边,很明显 \(O(n^2)\) 建边会挂一堆 . 那么考虑一下, \(n^2\) 建边多余的是哪些东西 \(???\) 很显然 ...

  7. 洛谷$P3645\ [APIO2015]$雅加达的摩天楼 最短路

    正解:最短路 解题报告: 传送门$QwQ$ 考虑暴力连边,发现最多有$n^2$条边.于是考虑分块 对于长度$p_i$小于等于$\sqrt(n)$的边,建立子图$d=p_i$.说下关于子图$d$的定义? ...

  8. 洛咕 P3645 [APIO2015]雅加达的摩天楼

    暴力连边可以每个bi向i+kdi连边权是k的边. 考虑这样的优化: 然后发现显然是不行的,因为可能还没有走到一个dog的建筑物就走了这个dog的边. 然后就有一个很妙的方法--建一个新的图,和原图分开 ...

  9. bzoj 4070 [Apio2015]雅加达的摩天楼 Dijkstra+建图

    [Apio2015]雅加达的摩天楼 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 644  Solved: 238[Submit][Status][D ...

随机推荐

  1. CSS3 nth-child的使用,详解css中nth的作用,以及nth-child的兼容写法

    :nth-child是css3的一个比较常用的选择器.它用于匹配属于其父元素中的子元素,不论元素的类型. 它的参数可以是数字.关键词或公式.下面讲介绍它的使用方法, nth-child的使用 html ...

  2. github检索小技巧

    GitHub筛选项目 首先打开主页 没有github账户的小伙伴先注册再登录 (其实不登录也可以下载项目) 登录状态的搜索框 未登录状态下的搜索框 点击搜索框输入内容 根据自己需要,输入关键字搜索 明 ...

  3. JSOI2016 病毒感染(动态规划)

    题目传送门:洛谷P5774 思路来源:郭大佬(我就是凑不要脸的白嫖党 : P) 题目分析: 我们一点点来分析这道题: 起点固定为1号,所有村庄是按线性排列的,而不是图,所以我们应该用线性DP(废话 ) ...

  4. 「JLOI2015」城池攻占 可并堆

    传送门 分析 如果直接暴力枚举的话肯定会超时 我们可以从下往上遍历,维护一个小根堆 每次到达一个节点把战败的骑士扔出去 剩下的再继续向上合并,注意要维护一下其实的战斗力 可以像线段树那样用一个lazy ...

  5. NOIP 2016 洛谷 P2827 蚯蚓 题解

    题目传送门 展开 题目描述 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手 ...

  6. DNP3协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析Modbus所含功能码

    现在网上有很多类似的文章.其实这一篇也借鉴了很多其他博主的文章. 写这篇文章的重点是在于解析功能和报文.对Dnp3这个协议并不会做很多介绍. 那我们就开始吧 上图则为dnp3协议整体的报文模型(点击红 ...

  7. 机器学习实战基础(二十四):sklearn中的降维算法PCA和SVD(五) PCA与SVD 之 重要接口inverse_transform

    重要接口inverse_transform  在上周的特征工程课中,我们学到了神奇的接口inverse_transform,可以将我们归一化,标准化,甚至做过哑变量的特征矩阵还原回原始数据中的特征矩阵 ...

  8. Python: 如何判断远程服务器上Excel文件是否被人打开

    最近工作中需要去判断远程服务器上的某个Excel文件是否被打开,如果被人打开,则等待,如果没人打开使用,则去填写数据进Excel文件. 开始想的很简单,和其他语言一样,比如C#,打开文件,如果报错说明 ...

  9. Web For Pentester靶场(xss部分)

    配置 官网:https://pentesterlab.com/ 下载地址:https://isos.pentesterlab.com/web_for_pentester_i386.iso 安装方法:虚 ...

  10. easyUI传递参数

    #======================JSP=====================================                <div class="l ...