博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
luogu P4082 [USACO17DEC]Push a Box
阅读量:4986 次
发布时间:2019-06-12

本文共 2833 字,大约阅读时间需要 9 分钟。

一个人推箱子,和之前的中的棋子移动有异曲同工之妙,因为每次可以让人走到箱子的其他方向上,或者推一下箱子

所以状态可以设成\(f_{i,j,k}\),即箱子在\((i,j)\),人在\(k\)方向的状态是否存在,一开始也要把人移到箱子旁边作为初始状态,然后每次移动人到箱子其他方位或者推箱子

难点是如何快速判断人是否可以从一个方位移到另一个方位上去.如果可以,说明至少存在一条不经过箱子的路径使得这两个方位联通,那么这两个位置也就是在同一个点双连通分量里面,\(tarjan\)即可

然后我发现自己一开始并不会求点双

还把转移的一个过程写错了

// luogu-judger-enable-o2#include
#define LL long long#define il inline#define re register#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))#define inf 1061109567using namespace std;const int N=1500+10,M=N*N*4;il LL rd(){ re LL x=0,w=1;re char ch=0; while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w;}int to[M<<1],nt[M<<1],hd[N*N],tot=1;il void add(int x,int y){ ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot; //++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;}int mm[4][2]={
{0,1},{1,0},{0,-1},{-1,0}};int n,m,qq,sx,sy,ex,ey,id[N][N],nxt[4]={2,3,0,1};bool a[N][N],f[N][N][4],v[N][N];int dfn[N*N],low[N*N],st[N*N],tp,ti,cnt;vector
inb[N*N];void tj(int x,int ffa){ dfn[x]=low[x]=++ti,st[++tp]=x; for(int i=hd[x];i;i=nt[i]) { int y=to[i]; if(!dfn[y]) { tj(y,x); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x]) { ++cnt; while(tp) { int z=st[tp--]; inb[z].push_back(cnt); if(y==z) break; } inb[x].push_back(cnt); } } else if(y!=ffa)low[x]=min(low[x],dfn[y]); }}il bool check(int x,int y){ for(int i=0,l1=inb[x].size();i
q; v[ex][ey]=true; q.push((nnn){ex,ey,0}); while(!q.empty()) { int x=q.front().x,y=q.front().y; q.pop(); for(int j=0;j<4;j++) { int xx=x+mm[j][0],yy=y+mm[j][1]; if(!a[xx][yy]||v[xx][yy]) continue; v[xx][yy]=true; q.push((nnn){xx,yy,0}); } } a[sx][sy]=true; for(int j=0;j<4;j++) { int xx=sx+mm[j][0],yy=sy+mm[j][1]; if(v[xx][yy]&&a[xx][yy]) f[sx][sy][j]=true,q.push((nnn){sx,sy,j}); } while(!q.empty()) { int x=q.front().x,y=q.front().y,fx=q.front().f; q.pop(); for(int j=0;j<4;j++) { int xx=x+mm[j][0],yy=y+mm[j][1]; if(j==nxt[fx]&&a[xx][yy]&&!f[xx][yy][fx]) { f[xx][yy][fx]=true; q.push((nnn){xx,yy,fx}); } int bx=x+mm[fx][0],by=y+mm[fx][1]; if(f[x][y][j]||!check(id[bx][by],id[xx][yy])) continue; f[x][y][j]=true; q.push((nnn){x,y,j}); } } while(qq--) { int x=rd(),y=rd(); bool ok=f[x][y][0]|f[x][y][1]|f[x][y][2]|f[x][y][3]|(x==sx&&y==sy); printf("%s\n",ok?"YES":"NO"); } return 0;}

转载于:https://www.cnblogs.com/smyjr/p/9706737.html

你可能感兴趣的文章
【Java POI】POI基于事件驱动解析大数据量2007版本Excel,空值导致列错位问题
查看>>
.Net_05_事务的基本语法(Sql 语句)
查看>>
c++ 获取某个进程个数
查看>>
SparkSQL相关语句总结
查看>>
[洛谷P1514]引水入城
查看>>
[NC189A]数字权重
查看>>
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
查看>>
VS2015和OpenCV配置
查看>>
PHP_D4_“简易聊天室 ”的具体技术实现
查看>>
[BAT]通过schtasks.exe远程调用windows 2008 server上的计划任务,提示ERROR : Access is denied...
查看>>
关于实习的一些问题
查看>>
Mybatis Insert、update、delete流程
查看>>
NameValueCollection与Hashtable的区别
查看>>
DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表
查看>>
Json对象的深浅拷贝
查看>>
HDOJ-1013
查看>>
A. Bus to Udayland
查看>>
Python 基础篇:字典、集合、文件操作
查看>>
Jmail发送邮件与带附件乱码解决办法
查看>>
分治法求一个N个元素数组的逆序数
查看>>