P3645 [APIO2015]雅加达的摩天楼 & ZLOJ练习

written on 2022-06-07

这道题暴力能拿90,然而我比较傻只拿了65

首先总结一下骗分的经验:因为这题刚开始我是用直接暴力加边的形式来搞的,这样的话要么会RE,要么会MLE。所以骗分的经验就是,如果发觉建边时可能爆空间,就可以采用不建边,在跑最短路的同时松弛能到的点这样的方法。

好了以上都是废话


正解的话,比赛的时候也想到了,这题其实还是蛮显然的。因为 doge 是以跳的形式来转移的,因此很容易就能想到根号分治

  • 对于 pn 的部分,可以直接建边,这部分复杂度为 O(nn)

  • 对于 p<n 的部分,这才是本题的关键。为了解决这一部分,正解是分层图最短路(真的没想到)

我们考虑以每一种跳跃能力 p 作为一层,在每一层内部加边权为 1 的边,这样的话,这一部分作为预处理的时间复杂度为 O(nn),也就是 p 的数量乘以点数 n,满足时间复杂度要求。同时,对于每一层的点(也就是这些虚点),向实际对应的点(也就是实点)连边权为 0 的边,对于这些 doge,向其对应的虚点连上入边。这样一来就能够保证时间复杂度了!

写完题解发现确实对这题的理解,以及对分层图最短路的理解增进了不少。分层图的相邻层之间连的边是那些免费的边,而这一题中,分层图相邻层之间不连边,只是作为一个预处理的过程来优化建边,也就是说分层图只是一个思想而非一个算法,它的拓展是很广泛的。

这题还需要注意一下细节,为了防止爆空间,我们选择把块长调到 min(n,100)

不知道为什么,这题 SPFA 好像会比 Dijkstra要快,然后的话,SPFAvis 数组记得每次出队时要清掉,敲代码的时候竟然忘记了

#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]);
}
posted @   Freshair_qprt  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示