BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
腊鸡题目,实在卡不过去。
(改了一下午)
就是裸的斯坦纳树的题目,一方面合并子集,另一方面SPFA迭代求解。
优化了许多地方,甚至基数排序都写了。
还是T到死,不打算改了,就这样吧
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define inf 0x3f3f3f3f
#define maxn 502
#define ll long long
#define mp make_pair short n,r,c,a[maxn][maxn];
int dp[maxn][maxn][10][10];
char s[maxn][maxn];
short mov[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
short go[maxn][maxn][4][2]; void Readin()
{
memset(dp,0x3f,sizeof dp);
cin>>n>>c>>r;
F(i,1,r)
{
scanf("%s",s[i]+1);
F(j,1,c)
{
switch(s[i][j])
{
case '.':a[i][j]=0;break;
case 'x':a[i][j]=-1;break;
case 'A':a[i][j]=10;break;
case 'C':a[i][j]=11;break;
default: a[i][j]=s[i][j]-'0';dp[i][j][a[i][j]][a[i][j]]=0;break;
}
}
}
F(i,0,r) a[i][0]=a[i][c+1]=-1;F(i,0,c) a[0][i]=a[r+1][i]=-1; a[r+1][c+1]=-1;
} int vis[maxn][maxn][4],idx; void dfs(int nx,int ny,int k)
{
int tmp=k;
if (vis[nx][ny][k]==idx)
{
go[nx][ny][k][0]=-1;
go[nx][ny][k][1]=-1;
return;
}
vis[nx][ny][k]=idx;
if (go[nx][ny][k][0]!=0) return;
switch(a[nx][ny])
{
case 10:tmp=(tmp+3)%4;break;
case 11:tmp=(tmp+1)%4;break;
}
if (a[nx+mov[tmp][0]][ny+mov[tmp][1]]==-1)
{
go[nx][ny][k][0]=nx;
go[nx][ny][k][1]=ny;
return;
}
int tx=nx+mov[tmp][0],ty=ny+mov[tmp][1];
if (!go[tx][ty][tmp][0]) dfs(tx,ty,tmp);
go[nx][ny][k][0]=go[tx][ty][tmp][0];
go[nx][ny][k][1]=go[tx][ty][tmp][1];
} void init()
{
F(i,1,r) F(j,1,c)
F(k,0,3){
int nx=i,ny=j,flag=1;++idx;
dfs(nx,ny,k);
}
} struct Statement{short x,y,l,r; int v;}sta[maxn*maxn],res[maxn*maxn];
queue <Statement> q,d;
int top=0; bool Com(Statement a, Statement b)
{return a.v<b.v;} int cnt[200005],ctop=0; void Radix_Sort()
{
memset(cnt,0,sizeof cnt);
F(i,1,top)
{
if (sta[i].v>=200000) continue;
cnt[sta[i].v]++,ctop=max(ctop,sta[i].v);
}
F(i,1,ctop) cnt[i]+=cnt[i-1]; int tmp=cnt[ctop];
F(i,1,top)
{
if (sta[i].v>=200000) continue;
res[cnt[sta[i].v]--]=sta[i];
}
F(i,1,tmp) sta[i]=res[i];
memcpy(sta,res,(top+1)*sizeof(Statement));
} void SPFA()
{
// sort(sta+1,sta+top+1,Com);
Radix_Sort();
F(i,1,top) q.push(sta[i]);
while (!q.empty()||!d.empty())
{
int nx,ny,l,r,v;
if (d.empty()||(!d.empty()&&!q.empty()&&q.front().v<=d.front().v))
{
Statement now=q.front(); q.pop();
nx=now.x,ny=now.y,l=now.l,r=now.r,v=now.v;
}
else
{
Statement now=d.front(); d.pop();
nx=now.x,ny=now.y,l=now.l,r=now.r,v=now.v;
}
if (dp[nx][ny][l][r]<v) continue;
for (int k=0;k<4;++k)
if (go[nx][ny][k][0]!=-1)
{
int tx=go[nx][ny][k][0],ty=go[nx][ny][k][1];
if (dp[tx][ty][l][r]>dp[nx][ny][l][r]+1)
{
dp[tx][ty][l][r]=dp[nx][ny][l][r]+1;
Statement now;
now.x=tx;now.y=ty;now.l=l;now.r=r;now.v=dp[tx][ty][l][r];
d.push(now);
}
}
}
}
void DP()
{
F(i,1,r) F(j,1,c) if (a[i][j]>=1&&a[i][j]<=n)
{++top;sta[top].x=i;sta[top].y=j;sta[top].l=a[i][j];sta[top].r=a[i][j];sta[top].v=dp[i][j][a[i][j]][a[i][j]];}
SPFA();
F(len,2,n)
{
F(i,1,n-len+1)
{
top=0;
int j=i+len-1;
F(x,1,r) F(y,1,c)
{
F(z,i,j-1) dp[x][y][i][j]=min(dp[x][y][i][z]+dp[x][y][z+1][j],dp[x][y][i][j]);
if (dp[x][y][i][j]<inf)
{
Statement now;
now.x=x;now.y=y;now.l=i;now.r=j;now.v=dp[x][y][i][j];
sta[++top]=now;
}
}
SPFA();
}
}
int ans=inf;
F(i,1,r) F(j,1,c) ans=min(ans,dp[i][j][1][n]);
printf("%d\n",ans==inf?-1:ans);
} int main()
{
Readin();
init();
DP();
}
BZOJ 3205 [Apio2013]机器人 ——斯坦纳树的更多相关文章
- [APIO2013]机器人(斯坦纳树)
题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人.任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人. 我们把机器人用 1 至 n 编号(n ≤ 9).如果两个机 ...
- bzoj 3205: [Apio2013]机器人【dfs+斯坦纳树+spfa】
第一次听说斯坦纳树这种东西 先dfs预处理出来dis[i][j][k]表示格子(i,j)向k方向转移能到哪,记忆话搜索预处理,注意如果有环的话特判一下 设f[i][j][x][y]表示复合机器人i-j ...
- [BZOJ3205][APIO2013]Robot(斯坦纳树)
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 1007 Solved: 240[Submit][Status ...
- bzoj 4006 管道连接 —— 斯坦纳树+状压DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...
- [Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 977 Solved: 230[Submit][Status] ...
- [APIO2013]机器人[搜索、斯坦纳树]
题意 题目链接 分析 记 g(d,x,y) 表示从 (x,y) 出发,方向为 d 到达的点,这个可以通过记忆化搜索求出,注意如果转移成环(此时向这个方向走没有意义)要特判. 记 f(l,r,x,y) ...
- BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)
题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...
- bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...
- bzoj 2595 [Wc2008]游览计划(斯坦纳树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...
随机推荐
- java 删除字符串最后一个字符的几种方法
偶然看到的,记录一下,以免忘记 字符串:string s = "1,2,3,4,5," 目标:删除最后一个 "," 方法: 1.用的最多的是Substri ...
- mysqldumpslow及explain使用简介
- 推荐一个markdown格式转html格式的开源JavaScript库
这个markdown格式转html格式的开源JavaScript库在github上的地址: https://github.com/millerblack/markdown-js 从markdown 格 ...
- C++通讯录
C++通讯录1.0 历时一天,终于把通讯录写好了. 项目要求: 编写一个通讯录管理程序. 有一已存在的通讯录文件,数据内容为各联系人信息. 每个联系人信息的组成部分为: 姓名.电话号码和住址 等个人基 ...
- Python 基础-3
使用while打印1 2 3 4 5 6 8 9 10 count = 0 #while count < 10: while count < 10: count += 1 if co ...
- Linux之Nginx服务 nfs文件存储 负载均衡
一.搭建Nginx服务 Nginx 是俄罗斯人编写的十分轻量级的HTTP 服务器,Nginx,它的发音为"engine X",是一个高性能的HTTP和反向代理服务器,同时也是一个I ...
- No package python-pip available
因为没有此rpm包,此包包含在epel源里面 输入rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarc ...
- Bootstrap 网格系统(Grid System)
Bootstrap 网格系统(Grid System) Bootstrap提供了一套响应式,移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. 什么是 ...
- ios之UIPageControl
分页控件是一种用来取代导航栏的可见指示器,方便手势直接翻页,最典型的应用便是iPhone的主屏幕,当图标过多会自动增加页面,在屏幕底部你会看到原点,用来只是当前页面,并且会随着翻页自动更新. 一.创建 ...
- Codeforces Round #510 #B
http://codeforces.com/contest/1042/problem/B 题意: 给出n种饮料,每种饮料还有一种或多种维生素(A或B或C),某人想集齐三种维生素,问最少需要花费多少? ...