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. HDFS和MR的配置和使用

    一.分布式HDFS的安装和启动 ①在$HADOOP_HOME/etc/hadoop/core-site.xml文件 <configuration> <property> < ...

  2. POJ 3057 Evacuation 题解

    题目 Fires can be disastrous, especially when a fire breaks out in a room that is completely filled wi ...

  3. 棋子游戏 51Nod - 1534 思维题

    题目描述 波雷卡普和瓦西里喜欢简单的逻辑游戏.今天他们玩了一个游戏,这个游戏在一个很大的棋盘上进行,他们每个人有一个棋子.他们轮流移动自己的棋子,波雷卡普先开始.每一步移动中,波雷卡普可以将他的棋子从 ...

  4. C#获取页面内容的几种方式

    常见的Web页面获取页面内容用 WebRequest 或者 HttpWebRequest 来操作 Http 请求. 例如,获取百度网站的 html 页面 var request = WebReques ...

  5. day39 作业

    实现生产消费原理 from multiprocessing import Process,JoinableQueue import time import random def cooker(q): ...

  6. df['']和df[['']]的区别

  7. softmax、cross entropy和softmax loss学习笔记

    之前做手写数字识别时,接触到softmax网络,知道其是全连接层,但没有搞清楚它的实现方式,今天学习Alexnet网络,又接触到了softmax,果断仔细研究研究,有了softmax,损失函数自然不可 ...

  8. AcWing 93. 递归实现组合型枚举

    AcWing 93. 递归实现组合型枚举 原题链接 从 1~n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案. 输入格式 两个整数 n,m ,在同一行用空格隔开. 输出格式 按照从小到大的 ...

  9. CSS定位布局

    CSS定位布局 基础知识 在CSS布局中,定位布局也是一种非常常见的技术手段,我们以京东为例: 上面是非常好的例子,对于定位布局来说它可以将一个元素放在页面上的任意一个位置. 但是定位布局也不能滥用, ...

  10. T133308 57级返校测试重测-T3-成绩单

    大致题意: 给定n个学生的学号和分数, 求各个分数段的人数, 求把学号排序后的序列, 求满分的人数以及学号. 基本思路: 虽然看起来很繁琐(?),但就非常非常的简单,直接按题意做就好了. 然后有个坑, ...