3205: [Apio2013]机器人

Time Limit: 15 Sec  Memory Limit: 128 MB
Submit: 1007  Solved: 240
[Submit][Status][Discuss]

Description

VRI(Voltron
机器人学会)的工程师建造了 n个机器人。任意两个兼容的机器人站在同一个格子时可以合并为一个复合机器人。我们把机器人用 1至 n编号(n ≤
9)。如果两个机器人的编号是连续的,那么它们是兼容的,可以合并成一个复合机器人。最初这   n  
个机器人各自都只有唯一的编号。而一个由两个或以上的机器人合并构成的复合机器人拥有两个编号,分别是构成它的所有机器人中最小和最大的编号。例如,
2号机器人只可以与 1号或 3号机器人合并。若 2号机器人与 3号机器人合并,可构成编号为 2-3的复合机器人。如果编号为
2-3的复合机器人与编号为 4-6的复合机器人合并,可构成编号为 2-6的复合机器人。当所有机器人合并以后则构成 1-n复合机器人。工程师把这
n个机器人放在了一个封闭的房间中,房间四周均是墙。该房间被划分成 w     h   
个方格。有些方格有障碍物,机器人不可经过或停留;其余方格允许多个机器人停留,同时允许机器人经过。任何时候一个机器人只占用一个方格。初始时刻,所有
机器人均在不同的方格中。这些原始的机器人不会自发地移动。它们只有被工程师沿   x轴或
y轴推动后,才会沿推动的方向不断向前直线移动,直至碰到障碍物或墙停止移动。停止移动后,它会扫描当前的格子是否存在可以与它合并的机器人,如果有,则
合并并继续检查,直至不能再合并为止。工程师只能沿水平向左、水平向右、竖直向上、竖直向下四个方向推动机器人,并且,在机器人尚未停止移动时,不允许推
动其它机器人,因此任何时刻,房间中都只能有一个机器人移动,为了帮助机器人转向,工程师在一些格子中放置了转向器。具体地说,转向器分为顺时针转向器
(右转器)和逆时针转向器(左转器),顺时针转向器可以使到达该格子的机器人沿顺时针方向转向  
90_;逆时针转向器可以使到达该格子的机器人沿逆时针方向转向
90_。现在,我们将告诉你初始时刻房间内的信息。请你计算工程师最少共计需要推动机器人多少次,才能把所有的 n个机器人全部合并(如果可能的话)。

Input

你的程序必须从标准输入读入。输入的第 1行包含 3个整数 n、w和 h,用空格隔开。输入文件中接下来的 h行描述初始时刻房间内的信息,每行包含w个字符。这w* h 字符中每一个表示房间中的一个格子,意义如下:
 
‘ 1’至‘9’:表示该方格中有一个机器人,编号为这个数字;
‘ x’:表示该方格有障碍物;
 
‘ A’:表示该方格中有一个逆时针转向器;
 
‘ C’:表示该方格中有一个顺时针转向器;
‘ .’:表示该方格为空地。

Output

你的程序必须输出到标准输出。输出仅一个整数,表示最少需要推动的次数。
若不能使所有机器人全部合并,输出-1。

Sample Input

4 10 5
1.........
AA...x4...
..A..x....
2....x....
..C.3.A...

Sample Output

5

HINT

第一步:向右推动 3 号机器人,当它碰到转向器后会向上继续移动,直至碰到墙壁停止移动。第二步:向上推动 4
号机器人,当它碰到墙壁后停止移动,与3 号机器人合并,构成  3-4 号机器人 第三步:向上推动 2
号机器人,当它碰到转向器后会向左移动,由于左侧为墙壁,故停留在原地。第四步:向右推动  2
号机器人,由于它在一个转向器上,故它会向上移动,直至碰到墙壁停止移动,与  1 号机器人合并,构成 1-2 号机器人。第五步:向左推动  3-4
号机器人,当它碰到墙壁后停止移动,与 1-2 号机器人合并,构成  1-4 号机器人。

n ≤ 9,w ≤ 500且   h ≤ 500

Source

[Submit][Status][Discuss]

都说是比较明显的斯坦纳树,但我并没有看出来,只是状态转移比较像而已,和连通性并没有什么关系(或许是合并的过程比较像最小生成树)。

http://wyfcyx.is-programmer.com/posts/75949.html

不好写,卡空间又卡时间。注意能用栈的不要用队列,栈的常数小不少。

不知道为什么按照lych的代码写的,改得几乎一样了,常数还要大一半。

还有那些用std::queue过的真心服气。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,M=N*N+,inf=0x3f3f3f3f;
const int dx[]={-,,,},dy[]={,,,-};
char ch;
struct P{ int x,y; }go[N][N][],q1[M],q2[M],pos[N];
int n,m,s,ans,tim,a[N][N],f[][][N][N],inq[N][N],vis[N][N][],c[M],val[M]; int add(int x){ x++; return (x>=M) ? x-M : x; }
void inc(int &x){ x=add(x); }
bool jud(int x,int y){ return x>= && x<=n && y>= && y<=m && a[x][y]!=; } P dfs(int x,int y,int d){
if (vis[x][y][d]==tim) return (P){-,-};
if (go[x][y][d].x || go[x][y][d].y) return go[x][y][d];
vis[x][y][d]=tim; int t=d;
if (a[x][y]==) t=(t+)%;
if (a[x][y]==) t=(t+)%;
int xx=x+dx[t],yy=y+dy[t];
if (!jud(xx,yy)) return go[x][y][d]=(P){x,y};
return go[x][y][d]=dfs(xx,yy,t);
} void spfa(int l,int r){
memset(inq,,sizeof(inq)); P ss;
int top=,st=,ed=,mn=inf,mx=-inf;
rep(x,,n) rep(y,,m) if (f[l][r][x][y]!=inf)
q1[++top]=(P){x,y},val[top]=f[l][r][x][y],mn=min(mn,val[top]),mx=max(mx,val[top]); rep(i,,mx) c[i]=;
rep(i,,top) c[val[i]]++;
rep(i,mn+,mx) c[i]+=c[i-];
for (int i=top; i; i--) q2[c[val[i]]--]=q1[i];
rep(i,,top) q1[i]=q2[top-i+]; while (top || st!=ed){
int now=add(st);
if (st==ed || (top && f[l][r][q1[top].x][q1[top].y]<f[l][r][q2[now].x][q2[now].y])) ss=q1[top--]; else ss=q2[st=now];
int x=ss.x,y=ss.y; inq[x][y]=;
rep(d,,){
P pp=go[x][y][d];
if (pp.x==x && pp.y==y) continue;
if (~pp.x && f[l][r][pp.x][pp.y]>f[l][r][x][y]+){
f[l][r][pp.x][pp.y]=f[l][r][x][y]+;
if (!inq[pp.x][pp.y]) inq[pp.x][pp.y]=,inc(ed),q2[ed]=pp;
}
}
}
} int main(){
freopen("bzoj3205.in","r",stdin);
freopen("bzoj3205.out","w",stdout);
scanf("%d%d%d",&s,&m,&n); ans=inf;
memset(f,0x3f,sizeof(f));
rep(i,,n) rep(j,,m){
scanf(" %c",&ch);
if (ch>='' && ch<=''){
int t=ch-'';
a[i][j]=t; pos[ch-'']=(P){i,j}; f[t][t][i][j]=;
}
if (ch=='A') a[i][j]=;
if (ch=='C') a[i][j]=;
if (ch=='x') a[i][j]=;
}
rep(i,,n) rep(j,,m) if (a[i][j]!=) rep(k,,) if (a[i][j]!=) tim++,go[i][j][k]=dfs(i,j,k);
rep(i,,s) f[i][i][pos[i].x][pos[i].y]=;
rep(l,,s) rep(i,,s-l+){
int j=i+l-;
rep(k,i,j-) rep(x,,n) rep(y,,m)
f[i][j][x][y]=min(f[i][j][x][y],f[i][k][x][y]+f[k+][j][x][y]);
spfa(i,j);
}
rep(x,,n) rep(y,,m) ans=min(ans,f[][s][x][y]);
printf("%d\n",(ans<inf)?ans:-);
return ;
}

[BZOJ3205][APIO2013]Robot(斯坦纳树)的更多相关文章

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

    题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人.任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人. 我们把机器人用 1 至 n 编号(n ≤ 9).如果两个机 ...

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

    腊鸡题目,实在卡不过去. (改了一下午) 就是裸的斯坦纳树的题目,一方面合并子集,另一方面SPFA迭代求解. 优化了许多地方,甚至基数排序都写了. 还是T到死,不打算改了,就这样吧 #include ...

  3. [Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)

    3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 977  Solved: 230[Submit][Status] ...

  4. [APIO2013]机器人[搜索、斯坦纳树]

    题意 题目链接 分析 记 g(d,x,y) 表示从 (x,y) 出发,方向为 d 到达的点,这个可以通过记忆化搜索求出,注意如果转移成环(此时向这个方向走没有意义)要特判. 记 f(l,r,x,y) ...

  5. bzoj 3205: [Apio2013]机器人【dfs+斯坦纳树+spfa】

    第一次听说斯坦纳树这种东西 先dfs预处理出来dis[i][j][k]表示格子(i,j)向k方向转移能到哪,记忆话搜索预处理,注意如果有环的话特判一下 设f[i][j][x][y]表示复合机器人i-j ...

  6. 【BZOJ2595】游览计划(状压DP,斯坦纳树)

    题意:见题面(我发现自己真是越来越懒了) 有N*M的矩阵,每个格子有一个值a[i,j] 现要求将其中的K个点(称为关键点)用格子连接起来,取(i,j)的费用就是a[i,j] 求K点全部连通的最小花费以 ...

  7. HDU 4085 斯坦纳树

    题目大意: 给定无向图,让前k个点都能到达后k个点(保护地)中的一个,而且前k个点每个需要占据后k个中的一个,相互不冲突 找到实现这个条件达到的选择边的最小总权值 这里很容易看出,最后选到的边不保证整 ...

  8. hdu4085 Peach Blossom Spring 斯坦纳树,状态dp

    (1)集合中元素表示(1<<i), i从0开始 (2)注意dp[i][ss] = min(dp[i][ss], dp[i][rr | s[i]] + dp[i][(ss ^ rr) | s ...

  9. hdu 3311 斯坦纳树

    思路:虚拟一个0号节点,将每个点建一条到0号节点的边,权值为挖井需要的价值.并要保证0号节点同另外n个寺庙一样被选择即可. 然后就是求斯坦纳树了. #include<map> #inclu ...

随机推荐

  1. 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树

    直接上代码 正所谓 人傻自带大常数 平衡树的几种姿势:  AVL Red&Black_Tree 码量爆炸,不常用:SBT 出于各种原因,不常用. 常用: Treap 旋转 基于旋转操作和随机数 ...

  2. [洛谷P2073] 送花

    送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花束,他不断地 ...

  3. ByteUtil 工具类

    ByteUtil 工具类 import java.io.FileOutputStream; import java.io.OutputStream; import java.nio.charset.C ...

  4. nginx的常规配置

    程序员们,在北上广你还能买房吗? >>>   nginx的常规配置 nginx的使用非常简单,只需要配置好我们需要的各种指令,就能跑起来.如果你需要添加模块,还需要添加模块方面的配 ...

  5. 【洛谷 P1070】道路游戏 (DP)

    题目链接 这题还是很好想的,看到\(90%\)的数据点时,我就知道要用\(n^3\)的算法(最后10分就算了吧) 然后,数据水,直接暴力\(n^3\)卡过了. 显然是道DP. 设\(f[i]\)表示第 ...

  6. jquery with ajax

    with session storage: 1.ajax请求可以放在 $(document).ready(function (){...}); 里. 2. $.ajax({ url: "/a ...

  7. linux shell 脚本实现tcp/upd协议通讯(重定向应用)

    linux shell 脚本实现tcp/upd协议通讯(重定向应用) http://www.cnblogs.com/chengmo/archive/2010/10/22/1858302.html

  8. Bean装配之@Autowired注解

    @Required(不常用) @Autowired(常用) 下面用例子解释以上内容: @Autowired注解的三种方式如下,第一种是直接在属性名上加注解,这样就可以不用在写set方法进行注入,这种方 ...

  9. 使用Python获取计算机名,ip地址,mac地址等等

    获取计算机名 # 获取计算机名,常用的方法有三种 import os import socket # method one name = socket.gethostname() print(name ...

  10. spring boot jar 进程自动停止,自动终止,不能后台持续运行

    第一次部署spring boot 到linux上,用命令java -jar **.jar,发现应用自动退出,进程停止了.后来发现要不挂断的执行命令,忽略所有的挂断信号,用以下命令解决 nohup ja ...