zoukankan      html  css  js  c++  java
  • 【BZOJ5138】[Usaco2017 Dec]Push a Box(强连通分量)

    【BZOJ5138】[Usaco2017 Dec]Push a Box(强连通分量)

    题面

    BZOJ
    洛谷

    题解

    这题是今天看到萝卜在做然后他一眼秒了,我太菜了不会做,所以就来做做。
    首先看完题目,是不是有点像(NOIP)的那道华容道?
    所以类似的考虑状态(f[x][y][d]),表示当前箱子在((x,y))位置,人在(d)(上下左右中的一个)方向时是否存在。那么这样子的状态数是(4nm)个,显然是可以的。考虑转移的话就是人推箱子了,沿着某个方向直接推是很容易的,现在的问题是如何让箱子不懂,换个方向。显然,如果箱子不动,人要换个方向的话,那么必定需要存在一条路径可以让人从一个方向走到另外一个方向,而箱子必定阻断了一条路径,所以等价于两个方向所在的点必定在一个点双内。那么把箱子扔掉,考虑所有空位置构成的点双,然后(bfs)一遍判断能否达到的所有位置即可。
    然后是傻逼yyb调了2h,然而竟然是把一个变量yy写成了y。yyb习惯性连打两个y

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define MAX 1555
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int n,m,q,dfn[MAX*MAX],low[MAX*MAX],tim,S[MAX*MAX],top,tot,cnt;
    int sx,sy,ex,ey,f[MAX][MAX][4];
    bool vis[MAX][MAX];
    char g[MAX][MAX];
    int bh[MAX][MAX];
    vector<int> G[MAX*MAX];
    int d[4][2]={-1,0,1,0,0,-1,0,1};
    struct Node{int x,y,d;};
    queue<Node> Q;
    void Tarjan(int x,int y,int fx,int fy)
    {
    	dfn[bh[x][y]]=low[bh[x][y]]=++tim;S[++top]=bh[x][y];
    	for(int i=0;i<4;++i)
    	{
    		int xx=x+d[i][0],yy=y+d[i][1];
    		if(g[xx][yy]=='#')continue;
    		if(xx==fx&&fy==yy)continue;
    		if(!dfn[bh[xx][yy]])
    		{
    			Tarjan(xx,yy,x,y);
    			low[bh[x][y]]=min(low[bh[x][y]],low[bh[xx][yy]]);
    			if(low[bh[xx][yy]]>=dfn[bh[x][y]])
    			{
    				++cnt;int v;
    				do{G[v=S[top--]].push_back(cnt);}while(v!=bh[xx][yy]);
    				G[bh[x][y]].push_back(cnt);
    			}
    		}
    		else
    			low[bh[x][y]]=min(low[bh[x][y]],dfn[bh[xx][yy]]);
    	}
    }
    void BFS1()
    {
    	Q.push((Node){sx,sy,0});vis[sx][sy]=true;
    	while(!Q.empty())
    	{
    		Node u=Q.front();Q.pop();
    		for(int i=0;i<4;++i)
    		{
    			int x=u.x+d[i][0],y=u.y+d[i][1];
    			if(g[x][y]=='#')continue;
    			if(x==ex&&y==ey){f[ex][ey][i^1]=true;continue;}
    			if(vis[x][y])continue;
    			vis[x][y]=true;Q.push((Node){x,y,0});
    		}
    	}
    }
    bool check(int a,int b,int x,int y)
    {
    	for(int i=0,l1=G[bh[a][b]].size();i<l1;++i)
    		for(int j=0,l2=G[bh[x][y]].size();j<l2;++j)
    			if(G[bh[a][b]][i]==G[bh[x][y]][j])
    				return true;
    	return false;
    }
    void BFS2()
    {
    	for(int i=0;i<4;++i)if(f[ex][ey][i])Q.push((Node){ex,ey,i});
    	while(!Q.empty())
    	{
    		Node u=Q.front();Q.pop();
    		//1.转到其它方向上面去
    		for(int i=0;i<4;++i)
    		{
    			if(f[u.x][u.y][i])continue;
    			int x=u.x+d[i][0],y=u.y+d[i][1];
    			if(g[x][y]=='#')continue;
    			if(check(u.x+d[u.d][0],u.y+d[u.d][1],x,y))
    				f[u.x][u.y][i]=true,Q.push((Node){u.x,u.y,i});
    		}
    		//2.推一步
    		int x=u.x+d[u.d^1][0],y=u.y+d[u.d^1][1];
    		if(g[x][y]!='#')
    			if(!f[x][y][u.d])
    				f[x][y][u.d]=true,Q.push((Node){x,y,u.d});
    	}
    }
    int main()
    {
    	n=read();m=read();q=read();
    	memset(g,'#',sizeof(g));
    	for(int i=1;i<=n;++i)scanf("%s",g[i]+1),g[i][m+1]='#';
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)
    			if(g[i][j]=='A')sx=i,sy=j,g[i][j]='.';
    			else if(g[i][j]=='B')ex=i,ey=j,g[i][j]='.';
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=m;++j)
    			if(g[i][j]!='#')bh[i][j]=++tot;
    	Tarjan(sx,sy,0,0);
    	BFS1();BFS2();
    	while(q--)
    	{
    		int x=read(),y=read();bool fl=(x==ex)&&(y==ey);
    		for(int i=0;i<4;++i)fl|=f[x][y][i];
    		puts(fl?"YES":"NO");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Handler一般处理程序的应用--随机图片生成
    一个内外网部署sharepoint的配置
    不使用SQL Server Management Studio备份数据库的方法
    根据模板生成网页
    一个简单的将Oracle生产库定期备份到备份库的方法
    c#序列化与反序列化
    The Java Reliable Multicast Service:A Reliable Multicast Library
    Video capture using JMF
    转:关于Jxta的Advertisement
    Practical JXTA II
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9700635.html
Copyright © 2011-2022 走看看