codevs 3290 华容道
HAHAHA
BFS+SPFA.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxn 35
#define maxv 100500
#define maxe 400500
#define inf 100000007
using namespace std;
struct edge
{
int v,w,nxt;
}e[maxe];
int n,m,qq,map[maxn][maxn],dp[maxn][maxn][],step[maxn][maxn][][],tot=,nume=,g[maxv],v[maxn][maxn][];
int dt[maxn][maxn],dx[]={-,,,},dy[]={,,-,},dis[maxv];
int ex,ey,sx,sy,tx,ty,s,t;
bool vis[maxv];
queue <int> q;
void addedge(int u,int v,int w)
{
e[++nume].v=v;
e[nume].w=w;
e[nume].nxt=g[u];
g[u]=nume;
}
void reset1()
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
for (int k=;k<=;k++)
for (int l=;l<=;l++)
step[i][j][k][l]=inf;
}
void reset2()
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
dt[i][j]=inf;
}
void reset3()
{
fill(dis+,dis+tot+,inf);
memset(vis,false,sizeof(vis));
}
bool judge(int x,int y)
{
if ((x>=) && (x<=n) && (y>=) && (y<=m) && (map[x][y]))
return true;
return false;
}
int bfs(int bx,int by,int tx,int ty)
{
while (!q.empty()) q.pop();
reset2();
q.push(bx);q.push(by);
dt[bx][by]=;
while (!q.empty())
{
int hx=q.front();q.pop();
int hy=q.front();q.pop();
if ((hx==tx) && (hy==ty)) return dt[tx][ty];
for (int i=;i<=;i++)
{
int rx=hx+dx[i],ry=hy+dy[i];
if ((judge(rx,ry) && (dt[rx][ry]>dt[hx][hy]+)))
{
dt[rx][ry]=dt[hx][hy]+;
q.push(rx);q.push(ry);
}
}
}
return inf;
}
void pre_bfs()
{
reset1();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
if (map[i][j])
{
map[i][j]=;
for (int k=;k<=;k++)
for (int l=;l<=;l++)
{
int ax,ay,bx,by;
ax=i+dx[k];ay=j+dy[k];
bx=i+dx[l];by=j+dy[l];
if (judge(ax,ay) && judge(bx,by))
{
int r=bfs(ax,ay,bx,by);
if (r!=inf)
step[i][j][k][l]=r;
}
}
map[i][j]=;
}
}
}
void pre_build()
{
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
if (judge(i,j))
{
for (int k=;k<=;k++)
for (int l=;l<=;l++)
{
int ax,ay,bx,by;
ax=i+dx[k];ay=j+dy[k];
bx=i+dx[l];by=j+dy[l];
if (judge(ax,ay) && (judge(bx,by)) && (step[i][j][k][l]!=inf))
addedge(v[i][j][k],v[bx][by][l^],step[i][j][k][l]+);
}
}
}
}
void build()
{
s=++tot;t=++tot;
for (int i=;i<=;i++)
{
if (judge(sx+dx[i],sy+dy[i]))
{
map[sx][sy]=;
int r=bfs(ex,ey,sx+dx[i],sy+dy[i]);
map[sx][sy]=;
if (r!=inf)
addedge(s,v[sx][sy][i],r);
}
if (judge(tx+dx[i],ty+dy[i]))
addedge(v[tx][ty][i],t,);
}
map[sx][sy]=;
}
int spfa()
{
if ((sx==tx) && (sy==ty)) return ;
if ((sx==ex) && (sy==ey)) return -;
if ((map[sx][sy]==) || (map[tx][ty]==)) return -;
build();
reset3();
while (!q.empty()) q.pop();
q.push(s);dis[s]=;vis[s]=true;
while (!q.empty())
{
int head=q.front();
q.pop();
for (int i=g[head];i;i=e[i].nxt)
{
int v=e[i].v;
if (dis[v]>dis[head]+e[i].w)
{
dis[v]=dis[head]+e[i].w;
if (!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
vis[head]=false;
}
if (dis[t]==inf) return -;
else return dis[t];
}
int main()
{
memset(g,,sizeof(g));
scanf("%d%d%d",&n,&m,&qq);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
scanf("%d",&map[i][j]);
for (int k=;k<=;k++)
v[i][j][k]=++tot;
}
pre_bfs();
pre_build();
for (int i=;i<=qq;i++)
{
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
printf("%d\n",spfa());
}
return ;
}
codevs 3290 华容道的更多相关文章
- codevs 3290 华容道(SPFA+bfs)
codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...
- 【CodeVS 3290】【NOIP 2013】华容道
http://codevs.cn/problem/3290/ 据说2013年的noip非常难,但Purpleslz学长还是AK了.能A掉这道题真心orz. 设状态$(i,j,k)$表示目标棋子在$(i ...
- 2013 Noip提高组 Day2
3288积木大赛 正文 题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前 ...
- codevs 3289 花匠
题目:codevs 3289 花匠 链接:http://codevs.cn/problem/3289/ 这道题有点像最长上升序列,但这里不是上升,是最长"波浪"子序列.用动态规划可 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
- codevs 1285 二叉查找树STL基本用法
C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...
- codevs 1576 最长上升子序列的线段树优化
题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...
- codevs 1080 线段树点修改
先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
随机推荐
- DevExpress控件使用系列--ASPxGridView+Popup+Tab
1.控件功能 列表控件展示数据.弹框控件执行编辑操作.Tab控件实现多标签编辑操官方说明 2.官方示例 2.1 ASPxGridView http ...
- Codeforces Round #256 (Div. 2) Multiplication Table
C题, #include<cstdio> #include<cstring> #include<algorithm> #define maxn 5005 using ...
- HTTP/2 对 Web 性能的影响(上)
一.前言 HTTP/2 于 2015 年 5 月正式推出.自诞生以来,它就一直在影响着网络性能最佳实践.在本篇文章中,我们将讨论 HTTP/2 的二进制帧.延迟削减.潜在利弊以及相应的应对措施. 超文 ...
- 【面试题030】最小的k个数
[面试题030]最小的k个数 题目: 输入n个整数,找出其中最小的k个数. 例如输入4.5.1.6.2.7.3.8这8个字,则其中最小的4个数字是1.2.3.4. 思路一: ...
- UVA 10000 Longest Paths (SPFA算法,模板题)
题意:给出源点和边,边权为1,让你求从源点出发的最长路径,求出路径长度和最后地点,若有多组,输出具有最小编号的最后地点. #include <iostream> #include < ...
- 【Linux高频命令专题(17)】head
概述 head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. 命令格式 hea ...
- 【Linux高频命令专题(5)】rmdir
简述 rmdir是常用的命令,该命令的功能是删除空目录,一个目录被删除之前必须是空的.(注意,rm - r dir命令可代替rmdir,但是有很大危险性.)删除某目录时也必须具有对父目录的写权限. 命 ...
- Nhibernate
Nhibernate入门与demo 学习和使用Nhibernate已经很久了,一直想写点东西和大家一起学习使用Nhibernate.博客园里也有很多大牛写了很多关于Nhibernate入门的文章.其中 ...
- Linux资源监控命令/工具(网络)
1.手动/自动设定与启动/关闭IP参数:ifconfig,ifup,ifdown 这三个指令的用途都是在启动网络接口,不过,ifup与ifdown仅能就/etc/sysconfig/netw ...
- Hibernate逍遥游记-第12章 映射值类型集合-001映射set(<element>)
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...