• [APIO2015]雅加达的摩天楼


    Description

    印尼首都雅加达市有 N 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 0 到 N−1。除了这 N 座摩天楼外,雅加达市没有其他摩天楼。
    有 M 只叫做 “doge” 的神秘生物在雅加达市居住,它们的编号依次是 0 到 M−1。编号为 i 的 doge 最初居住于编号为 Bi 的摩天楼。每只 doge 都有一种神秘的力量,使它们能够在摩天楼之间跳跃,编号为 i 的 doge 的跳跃能力为 Pi (Pi>0)。
    在一次跳跃中,位于摩天楼 b 而跳跃能力为 p 的 doge 可以跳跃到编号为 b−p (如果 0≤b−p<N)或 b+p (如果 0≤b+p<N)的摩天楼。
    编号为 0 的 doge 是所有 doge 的首领,它有一条紧急的消息要尽快传送给编 号为 1 的 doge。任何一个收到消息的 doge 有以下两个选择:
    跳跃到其他摩天楼上;
    将消息传递给它当前所在的摩天楼上的其他 doge。
    请帮助 doge 们计算将消息从 0 号 doge 传递到 1 号 doge 所需要的最少总跳跃步数,或者告诉它们消息永远不可能传递到 1 号 doge。

    Input

    输入的第一行包含两个整数 N 和 M。
    接下来 M 行,每行包含两个整数 Bi 和 Pi。

    Output

    输出一行,表示所需要的最少步数。如果消息永远无法传递到 1 号 doge,输出 −1。
    Sample Input
    5 3

    0 2

    1 1

    4 1
    Sample Output
    5

    explanation

    下面是一种步数为 5 的解决方案:

    0 号 doge 跳跃到 2 号摩天楼,再跳跃到 4 号摩天楼(2 步)。

    0 号 doge 将消息传递给 2 号 doge。

    2 号 doge 跳跃到 3 号摩天楼,接着跳跃到 2 号摩天楼,再跳跃到 1 号摩天楼(3 步)。

    2 号 doge 将消息传递给 1 号 doge。
    HINT
    子任务

    所有数据都保证 0≤Bi<N。

    子任务 1 (10 分)

    1≤N≤10

    1≤Pi≤10

    2≤M≤3

    子任务 2 (12 分)

    1≤N≤100

    1≤Pi≤100

    2≤M≤2000

    子任务 3 (14 分)

    1≤N≤2000

    1≤Pi≤2000

    2≤M≤2000

    子任务 4 (21 分)

    1≤N≤2000

    1≤Pi≤2000

    2≤M≤30000

    子任务 5 (43 分)

    1≤N≤30000

    1≤Pi≤30000

    2≤M≤30000

    题解

    这道题一看就知道是个最短路嘛。
    但是你如果暴力连边,最多可能会出现 (n^2)条边。
    所以我们考虑分块。
    对于能力值大于$ sqrt n $ 的怪兽,我们暴力连边。
    对于能力值小于$ sqrt n $ 的怪兽,我们把整个网络分为$ sqrt n $ 层,每层从起点分别向后连边。这样就保证了边数小于$ nsqrt n $ 。就可以跑最短路了。

    Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define ll long long
    #define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
    #define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
    #define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
    inline int read()
    {
    	int sum=0,p=1;char ch=getchar();
    	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
    	if(ch=='-')p=-1,ch=getchar();
    	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
    	return sum*p;
    }
    
    const int maxn=3e4+20;
    int n,m,t;
    
    struct node {
    	int v,next,w;
    };
    node e[maxn*500];
    int cnt,start[100*maxn];
    int p[101][maxn];
    
    int st,en;
    int num;
    void addedge(int u,int v,int w)
    {
    	e[++cnt]={v,start[u],w};
    	start[u]=cnt;
    }
    
    void init()
    {
    	n=read();m=read();
    	t=min(100,(int)sqrt(n));
    	num=n-1;
    	REP(i,1,t)
    	{
    		REP(j,0,i-1)
    		{
    			for(int k=j;k<n;k+=i)
    			{
    				p[i][k]=++num;
    				addedge(num,k,0);
    				if(k>=i)addedge(num-1,num,1),addedge(num,num-1,1);
    			}
    		}
    	}
    	REP(i,1,m)
    	{
    		int a=read(),b=read();
    		if(i==1)st=a;if(i==2)en=a;
    		if(b>t)
    		{
    			for(int j=1;a+j*b<n;j++)addedge(a,a+j*b,j);
    			for(int j=1;a-j*b>=0;j++)addedge(a,a-j*b,j);
    		}else
    		{
    			addedge(a,p[b][a],0);
    		}
    	}
    }
    #include<queue>
    int dist[maxn*101],vis[maxn*101];
    int q[maxn*100];
    int N=maxn*100;
    
    void doing()
    {
    	int head=0,tail=1;
    	//memset(dist,30,sizeof(dist));
    	REP(i,0,num)dist[i]=1<<30;
    	dist[st]=0;
    	q[tail]=st;
    	vis[st]=1;
    	do{
    		head++;if(head==N-1)head=0;
    		int u=q[head];vis[u]=0;
    		EREP(i,u)
    		{
    			int v=e[i].v;
    			if(dist[v]>dist[u]+e[i].w)
    			{
    				dist[v]=dist[u]+e[i].w;
    				if(!vis[v])
    				{
    					vis[v]=1;
    					//q.push(v);
    					tail++;if(tail==N-1)tail=0;
    					q[tail]=v;
    				}
    			}
    		}
    	}while(head<tail);
    	if(dist[en]!=(1<<30))cout<<dist[en]<<endl;
    	else cout<<-1<<endl;
    }
    
    int main()
    {
    	init();
    	doing();
    	return 0;
    }
    
    
    
    
    
  • 相关阅读:
    Unity 粒子系统 特效 移除屏幕外面后再移回来 不会显示问题
    同步读取各平台StreamingAssets文件
    cocos2d-x for android 环境搭建&交叉编译
    lua 热更新
    php连接mysql超时问题
    svn仓库自动同步(主库、从库自动同步)
    游戏开发进度、状况以及结果的关系(个人感言)
    centos 重启服务命令
    编译时,输出信息重定向到文件
    vs开发的程序内存错误
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7257575.html
Copyright © 2020-2023  润新知