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个点连通. [科普] ...
随机推荐
- freebsd自动获取ip地址
最小化安装完成freebsd后,ifconfig查看不到ip地址 修改/etc/rc.conf 添加ifconfig_网卡名称="DHCP" 重启服务器或者sh /etc/rc.c ...
- 【春节版】年度精品 XP,32/64位Win7,32/64位Win8,32/64位Win10系统
本系统是10月5日最新完整版本的Windows10 安装版镜像,win10正式版,更新了重要补丁,提升应用加载速度,微软和百度今天宣布达成合作,百度成为win10 Edge浏览器中国默认主页和搜索引擎 ...
- [习题]输入自己的生日(年/月/日)#2 -- 日历(Calendar)控件的时光跳跃,一次跳回五年、十年前?--TodaysDate属性、VisibleDate属性
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/06/10/calendar_visibledate_birthday_dropdow ...
- The Django Book 第三章 试图和URL配置
之前自学Django也有一段时间了,再过一个月就要入职新公司了(Python Django开发),即使现在还在入门级徘徊,再好好把Django基础过一遍吧. The Django Book 第三章 试 ...
- 漫谈 Clustering (4): Spectral Clustering<转载>
转自http://blog.pluskid.org/?p=287 如果说 K-means 和 GMM 这些聚类的方法是古代流行的算法的话,那么这次要讲的 Spectral Clustering 就可以 ...
- MySQL查询当天数据以及大量查询时提升速度
select * from 表名 where to_days(字段名) = to_days(now()) 一.数据库设计方面1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...
- Python基础篇 -- 运算符和编码
运算符 记熟 ! ! ! 2**1=2 2**2=4 2**3=8 2**4=16 2**5=32 2**6=64 2**7=128 2**8=256 2**9=512 2**10=1024 运算符 ...
- jsTree展开根节点 设置用户图标
$("#jstree").on("loaded.jstree", function (event, data) { var n = 0; var root = ...
- 响应式Web设计- 图片
使用width属性:如果width属性设置为100%,图片会根据上下范围实现响应式的功能. <!DOCTYPE html><html><head><meta ...
- 全面解读Oracle同义词的概念作用、创建删除查看及Oracle的db link
Oracle的同义词(synonyms)从字面上理解就是别名的意思,和视图的功能类似,就是一种映射关系. 在Oracle中对用户的管理是使用权限的方式来管理的,也就是说,如果我们想使用数据库,我们就必 ...