欢迎来到SFWR的博客

P1979 华容道

 

————————————————————————————————————————————————————————————

毒瘤搜索+图论,只想到了其中一部分,没想起来对图进行预处理,再跑SPFA

————————————————————————————————————————————-

#include<bits/stdc++.h>
using namespace std;
struct Edge{int nxt,to,dis;}eg[300005];
struct node{int x,y,d;};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
int n,m,q,maps[35][35],num[35][35][4],tot,head[3005],ne,dis[50005],sx,sy,ex,ey,bx,by;
bool flag[35][35];
void add(int u,int v,int dis){eg[++ne].nxt=head[u];eg[ne].to=v;eg[ne].dis=dis;head[u]=ne;}
int bfs(int stx,int sty,int edx,int edy,int rtx,int rty)
{
    if(stx==edx&&sty==edy)return 0;
    memset(flag,0,sizeof(flag));
    queue <node> M;
    node u0;
    u0.x=stx;
    u0.y=sty;
    u0.d=0;
    M.push(u0);
    while(!M.empty())
    {
        node u=M.front();
        M.pop();
        int x=u.x,y=u.y,d=u.d;
        for(int i=0;i<=3;i++)
        {
            int xx=x+dx[i],yy=y+dy[i];
            if(!maps[xx][yy]||(xx==rtx&&yy==rty)||flag[xx][yy])continue;
            if(xx==edx&&yy==edy)return d+1;
            flag[xx][yy]=1;
            node tt;
            tt.x=xx;tt.y=yy;tt.d=d+1;
            M.push(tt);
        }
    }
    return 0x3f3f3f3f;
}
int spfa()
{
    if(sx==ex&&sy==ey)return 0;
    memset(dis,0x3f,sizeof(dis));
    queue <int> M;
    for(int i=0;i<=3;i++)
    {
        int x=sx+dx[i],y=sy+dy[i];
        if(num[sx][sy][i])
        {
            dis[num[sx][sy][i]]=bfs(bx,by,x,y,sx,sy);
            M.push(num[sx][sy][i]);
        }
    }//移动到制定格子 
    while(!M.empty())
    {
        int u=M.front();
        M.pop();
        for(int i=head[u];i;i=eg[i].nxt)
        {
            int to=eg[i].to;
            if(dis[to]>dis[u]+eg[i].dis)
            {
                dis[to]=dis[u]+eg[i].dis;
                M.push(to);
            }
        }
    }
    int ans=0x3f3f3f3f;
    for(int i=0;i<=3;i++)
    if(num[ex][ey][i])
    ans=min(ans,dis[num[ex][ey][i]]);
    if(ans==0x3f3f3f3f)ans=-1;
    return ans;
}
int main()
{
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) cin>>maps[i][j];
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) 
    for(int k=0;k<=3;k++)
    if(maps[i][j]&&maps[i+dx[k]][j+dy[k]])
    num[i][j][k]=++tot;//记录所有状态 
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) 
    for(int k=0;k<=3;k++)
    if(num[i][j][k])
    add(num[i][j][k],num[i+dx[k]][j+dy[k]][k^1],1);
    //连接交换边 
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) 
    for(int k=0;k<=3;k++)for(int t=0;t<=3;t++)
    if(k!=t&&num[i][j][k]&&num[i][j][t])
    add(num[i][j][k],num[i][j][t],bfs(i+dx[k],j+dy[k],i+dx[t],j+dy[t],i,j));
    //连接相连边 
    while(q--)
    {
           cin>>bx>>by>>sx>>sy>>ex>>ey;
        cout<<spfa()<<endl;
    }
}

 

posted @ 2019-06-05 21:40  SFWR  Views(152)  Comments(0Edit  收藏  举报