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个点连通. [科普] ...
随机推荐
- uvm_transaction——事物
文件: src/base/uvm_transaction.svh 类: uvm_transaction uvm_transaction继承自uvm_object,添加了timing和record ...
- 洛谷 P2264 情书
题目背景 一封好的情书需要撰写人全身心的投入.lin_toto同学看上了可爱的卡速米想对她表白,但却不知道自己写的情书是否能感动她,现在他带着情书请你来帮助他. 题目描述 为了帮助lin_toto,我 ...
- TLint for 虎扑体育应用源码项目
虎扑非官方客户端TLint全新Material Design设计,简洁美观支持论坛全部操作,浏览帖子.点亮.回复.引用.收藏等多项个性化设置(不同主题,不同阅读模式) TLint For 虎扑体育 更 ...
- UVA 10735 Euler Circuit (最大流)
题意:求混合图的欧拉路径. 一句话总结:网络流,最主要在于建图,此题是将出度则是和流量联系在了一起,用最大流来调整边的指向. 分析: 这题的困难之处在于无向边只能用一次,相当于一个方向未定的有向边. ...
- 线段树成段更新模板POJ3468 zkw以及lazy思想
别人树状数组跑几百毫秒 我跑 2500多 #include<cstdio> #include<map> //#include<bits/stdc++.h> #inc ...
- Shell脚本之for循环、while循环,if语句、case语句
1. for循环一般格式: 格式1: for((条件)) do 动作 done 格式2: for 变量名 in 范围 do 动作 done1234567891011121314实验:##1. 输出数字 ...
- jQuery中ready方法的实现
https://blog.csdn.net/major_zhang/article/details/80146674 先普及一下jquery.ready()和window.onload,window. ...
- 判断一个链表是否为回文结构 【题目】 给定一个链表的头节点head,请判断该链表是否为回 文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。 15->6->15,返回true。 1->2->3,返回false。 进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 度达到O(1)。
方式1:借助栈 空间辅助度是O(N) 方式2: 借助栈 空间复杂度是 O(n/2).只存后半个链表 方式3: 反转后半个链表 最后再反转回来 package my_basic.class_3; im ...
- linux 常用命令(持续更新)
查看IP地址 ifconfig 查看TCP端口 netstat -ntlp vi 文本编辑 (1)进入vi编辑模式 在vi的默认模式中,直接在界面中输入: i 在光标所在位置开始编辑: a 在光标所在 ...
- Bootstrap响应式布局(1)
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...