[APIO2013]机器人

Posted Tan_tan_tann

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[APIO2013]机器人相关的知识,希望对你有一定的参考价值。

机器人

题解

**卡常题

首先,由于一个机械人只能往 4 4 4个方向走,而每个点往一个方向走最终停留下来的点是固定的,我们可以考虑每个点往每个方向走走到的点先预处理出来,建个新图。

由于它要求只有编号连续的机械人在同一个节点上是才能够合并,所以我们可以考虑区间 d p dp dp
定义 d p l , r , i , j dp_{l,r,i,j} dpl,r,i,j表示编号区间为 [ l , r ] [l,r] [l,r]的机械人走到格子 ( i , j ) (i,j) (i,j)上时最小的代价,容易得到 d p dp dp转移方程式:
d p l , r , i , j = min ⁡ k = l r − 1 ( d p l , k , i , j + d p k + 1 , r , i , j , d p l , r , i , j ) dp_{l,r,i,j}=\\min_{k=l}^{r-1}\\left(dp_{l,k,i,j}+dp_{k+1,r,i,j},dp_{l,r,i,j}\\right) dpl,r,i,j=k=lminr1(dpl,k,i,j+dpk+1,r,i,j,dpl,r,i,j)
d p l , r , t o i , j , k = min ⁡ ( d p l , r , t o i , j , k , d p l , r , i , j + 1 ) dp_{l,r,to_{i,j,k}}=\\min\\left(dp_{l,r,to_{i,j,k}},dp_{l,r,i,j}+1\\right) dpl,r,toi,j,k=min(dpl,r,toi,j,k,dpl,r,i,j+1)
第一个式子主要涉及同一个节点上区间的合并,而第二个式子这是机械人在图上得移动。
对于第一个式子,直接转移即可。
对于第二个式子,这是一个多元的最短路,我们可以考虑用 S P F A SPFA SPFA来进行维护。
直接对于每个 ( l , r ) (l,r) (l,r)暴力进行区间转移与最短路即可。

但不幸的时,直接暴力 S P F A SPFA SPFA是会 T T T飞的,考虑优化。
然后我们就要开始加上一些稀奇古怪的优化了。
L L L LLL LLL S L F SLF SLF优化当然是必须的,不过实际上 L L L LLL LLL好像没多大用 (指算法)
我们在将 S P F A SPFA SPFA的起始点加入队列时需要先将其按 d p l , r , i , j dp_{l,r,i,j} dpl,r,i,j的值排序,再加入队列,以保证最开始的起点竟可能的小。
然后就是 S P F A SPFA SPFA选起点时可以选择队列前两个点中较小的一个,将大的放回队首。
注意 L L L LLL LLL优化记录 s u m sum sum时要开 l o n g l o n g longlong longlong,否则会在 u o j uoj uoj上挂掉。

然后,统计答案即可。
时间复杂度达到了惊人的 O ( n 3 h w + n 2 ( h w ) 2 ( ? ) ) O\\left(n^3hw+n^2(hw)^2(?)\\right) O(n3hw+n2(hw)2(?))
话说这能过真的正常吗?

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int inv2=499122177;
const int jzm=2333;
const int orG=3,invG=332748118;
const int lim=300000;
const double Pi=acos(-1.0);
typedef pair<int,int> pii;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y){return x+y<mo?x+y:x+y-mo;}
int qkpow(int a,int s){int t=1;while(s){if(s&1)t=1ll*a*t%mo;a=1ll*a*a%mo;s>>=1;}return t;}
int dx[5]={1,0,-1,0},dy[5]={0,1,0,-1};
int n,w,h,ans,l,r,to[MAXN][5];
int dp[12][12][MAXN];char maze[505][505];
int head,tail,stak,q[MAXN],sta[MAXN];
bool vis[5][505][505],inq[MAXN];
inline int Hash(pii x){return (x.fir-1)*w+x.sec;}
int dosaka(int x,int y,int f){
	int id=Hash(mkpr(x,y));if(vis[f][x][y])return to[id][f];
	to[id][f]=Hash(mkpr(-1,-1));vis[f][x][y]=1;int tf=f;
	if(maze[x][y]=='A')f=f>2?f-3:f+1;
	if(maze[x][y]=='C')f=f>0?f-1:f+3;
	int tx=x+dx[f],ty=y+dy[f];
	if(tx<1||ty<1||tx>h||ty>w)return to[id][tf]=id;
	if(maze[tx][ty]=='x')return to[id][tf]=id;
	return to[id][tf]=dosaka(tx,ty,f);
}
bool cmp(int x,int y){return dp[l][r][x]<dp[l][r][y];}
inline int adhead(){int tp=head;head++;if(head>lim)head=1;return tp;}
inline int adtail(){int tp=tail;tail++;if(tail>lim)tail=1;return tp;}
inline int rehead(){head--;if(head<1)head=lim;return head;}
signed main(){
	read(n);read(w);read(h);ans=INF;
	for(reg int i=1;i<=h;++i)scanf("\\n%s",maze[i]+1);
	for(int l=以上是关于[APIO2013]机器人的主要内容,如果未能解决你的问题,请参考以下文章

[APIO2013]机器人

[APIO2013]机器人(斯坦纳树)

bzoj3205: [Apio2013]机器人

Luogu P3638 [APIO2013]机器人

BZOJ 3205 [Apio2013]机器人 ——斯坦纳树

bzoj千题计划230:bzoj3205: [Apio2013]机器人