P3645 [APIO2015]雅加达的摩天楼 & ZLOJ练习
written on 2022-06-07
这道题暴力能拿90,然而我比较傻只拿了65。
首先总结一下骗分的经验:因为这题刚开始我是用直接暴力加边的形式来搞的,这样的话要么会RE,要么会MLE。所以骗分的经验就是,如果发觉建边时可能爆空间,就可以采用不建边,在跑最短路的同时松弛能到的点这样的方法。
好了以上都是废话
正解的话,比赛的时候也想到了,这题其实还是蛮显然的。因为
-
对于
的部分,可以直接建边,这部分复杂度为 。 -
对于
的部分,这才是本题的关键。为了解决这一部分,正解是分层图最短路(真的没想到)。
我们考虑以每一种跳跃能力
写完题解发现确实对这题的理解,以及对分层图最短路的理解增进了不少。分层图的相邻层之间连的边是那些免费的边,而这一题中,分层图相邻层之间不连边,只是作为一个预处理的过程来优化建边,也就是说分层图只是一个思想而非一个算法,它的拓展是很广泛的。
这题还需要注意一下细节,为了防止爆空间,我们选择把块长调到
不知道为什么,这题 然后的话,。
#include<bits/stdc++.h>
#define N 10000005
#define M 20000005
using namespace std;
int n,m,d[N];
int st,ed;
int tot,tot2,head[N],ver[M],nxt[M],edge[M];
void add_E(int x,int y,int z){ver[++tot]=y,edge[tot]=z,nxt[tot]=head[x],head[x]=tot;}
bool vis[N];
int id(int dep,int x){return dep*n+x;}
queue<int> q;
void SPFA()
{
memset(d,0x3f,sizeof(d));
d[st]=0;
q.push(st);
while(q.size())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i];
if(d[y]>d[x]+z)
{
d[y]=d[x]+z;
if(!vis[y]) vis[y]=1,q.push(y);
}
}
}
}
void build(int x)
{
for(int i=1;i<=n;i++)
{
if(i+x<=n) add_E(id(x,i),id(x,x+i),1),add_E(id(x,x+i),id(x,i),1);
add_E(id(x,i),i,0);
}
}
//id(x,i) refers to the one at i,its ability is x
bool mark[30005];
int main()
{
scanf("%d%d",&n,&m);
int B=min(100,(int)sqrt(n));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x++;
if(i==1) st=x;
else if(i==2) ed=x;
if(y>=B)
{
for(int j=x+y,cnt=1;j<=n;j+=y,cnt++) add_E(x,j,cnt);
for(int j=x-y,cnt=1;j>=1;j-=y,cnt++) add_E(x,j,cnt);
}
else
{
add_E(x,id(y,x),0);
if(!mark[y]) build(y),mark[y]=1;
}
}
SPFA();
if(d[ed]>=1e9) puts("-1");
else printf("%d\n",d[ed]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!