腊鸡题目,实在卡不过去。

(改了一下午)

就是裸的斯坦纳树的题目,一方面合并子集,另一方面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]机器人 ——斯坦纳树的更多相关文章

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

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

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

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

  3. [BZOJ3205][APIO2013]Robot(斯坦纳树)

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

  4. bzoj 4006 管道连接 —— 斯坦纳树+状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4006 用斯坦纳树求出所有关键点的各种连通情况的代价,把这个作为状压(压的是集合选择情况)的初 ...

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

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

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

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

  7. BZOJ 4006 Luogu P3264 [JLOI2015]管道连接 (斯坦纳树、状压DP)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4006 (luogu)https://www.luogu.org/probl ...

  8. bzoj 4006 [JLOI2015]管道连接(斯坦纳树+状压DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4006 [题意] 给定n点m边的图,连接边(u,v)需要花费w,问满足使k个点中同颜色的 ...

  9. bzoj 2595 [Wc2008]游览计划(斯坦纳树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...

随机推荐

  1. 查询sqlserver数据库,表占用数据大小

     if exists(select 1 from tempdb..sysobjects where id=object_id('tempdb..#tabName') and xtype='u')dro ...

  2. php 小坑记录

    1 empty  PHP<=5.5不能用于判断一个表达式的执行结果并且netbeans 和eclipse编辑器识别不出来此错误 含有此用法的 类 和页面将会报错 empty($this-> ...

  3. 纪念一下我的第一个php扩展

    C扩展代码 生成 so扩展文件( 很多文章介绍 生成so时候 喜欢用 # phpize ./configure ...... 刚开始掉进坑里面出不来 就是因为把这两个命令看成了一个 phpize ./ ...

  4. 人人必知的10个 jQuery 小技巧

    原文地址:http://info.9iphp.com/10-jquery-tips-everyone-should-know/ 人人必知的10个 jQuery 小技巧   收集的10个 jQuery ...

  5. 补题—Codeforces Round #346 (Div. 2) _智商欠费系列

    这次的题目相对容易 但是智商依旧不够用 原因有三点 1.英文水平堪忧 2 逻辑不严密 3 细节掌握不够好 传送门 http://codeforces.com/contest/659 A 题目大意 圆环 ...

  6. KTU Programming Camp (Winter Training Day 1)

    A.B.C(By musashiheart) 0216个人赛前三道题解 E(By ggg) Gym - 100735E Restore H(by pipixia) Gym - 100735H

  7. bzoj 2658

    首先考虑容斥 我们计算出所有没有点在其中的矩形,然后用所有矩形减去这些矩形即可 然后考虑如何计算没有点在其中的矩形 采用扫描线的思想,从上向下一行一行扫,假设我们扫到的行编号是$a$,然后考虑如果左右 ...

  8. Jordan 标准型定理

    将学习到什么 就算两个矩阵有相同的特征多项式,它们也有可能不相似,那么如何判断两个矩阵是相似的?答案是它们有一样的 Jordan 标准型.   Jordan 标准型定理 这节目的:证明每个复矩阵都与一 ...

  9. pre-receive hook declined

    没有master分支的代码提交权限. 分配权限或者提交分支合并申请

  10. Java InputStream、String、File相互转化

    String --> InputStreamByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes()); Inp ...