codevs 3290 华容道

Posted on 2016-08-09 00:43  ziliuziliu  阅读(147)  评论(0编辑  收藏  举报

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][4],step[maxn][maxn][4][4],tot=0,nume=0,g[maxv],v[maxn][maxn][4];
int dt[maxn][maxn],dx[]={-1,1,0,0},dy[]={0,0,-1,1},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=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            for (int k=0;k<=3;k++)
                for (int l=0;l<=3;l++)
                    step[i][j][k][l]=inf;
}
void reset2()
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            dt[i][j]=inf;
}
void reset3()
{
    fill(dis+1,dis+tot+1,inf);
    memset(vis,false,sizeof(vis));
}
bool judge(int x,int y)
{
    if ((x>=1) && (x<=n) && (y>=1) && (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]=0;
    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=0;i<=3;i++)
        {
            int rx=hx+dx[i],ry=hy+dy[i];
            if ((judge(rx,ry) && (dt[rx][ry]>dt[hx][hy]+1)))
            {
                dt[rx][ry]=dt[hx][hy]+1;
                q.push(rx);q.push(ry);
            }
        }
    }
    return inf;
}
void pre_bfs()
{
    reset1();
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            if (map[i][j])
            {
                map[i][j]=0;
                for (int k=0;k<=3;k++)
                    for (int l=0;l<=3;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]=1;
            }
        }
}
void pre_build()
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            if (judge(i,j))
            {
                for (int k=0;k<=3;k++)    
                    for (int l=0;l<=3;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^1],step[i][j][k][l]+1);
                    }
            }
        }
}
void build()
{
    s=++tot;t=++tot;
    for (int i=0;i<=3;i++)
    {
        if (judge(sx+dx[i],sy+dy[i]))
        {
            map[sx][sy]=0;
            int r=bfs(ex,ey,sx+dx[i],sy+dy[i]);
            map[sx][sy]=1;
            if (r!=inf)
                addedge(s,v[sx][sy][i],r);
        }
        if (judge(tx+dx[i],ty+dy[i]))
            addedge(v[tx][ty][i],t,0);
    }
    map[sx][sy]=1;
}
int spfa()
{
    if ((sx==tx) && (sy==ty)) return 0;
    if ((sx==ex) && (sy==ey)) return -1;
    if ((map[sx][sy]==0) || (map[tx][ty]==0)) return -1;
    build();
    reset3();
    while (!q.empty()) q.pop();
    q.push(s);dis[s]=0;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 -1;
    else return dis[t];
}
int main()
{
    memset(g,0,sizeof(g));
    scanf("%d%d%d",&n,&m,&qq);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            scanf("%d",&map[i][j]);
            for (int k=0;k<=3;k++)
                v[i][j][k]=++tot;
        }
    pre_bfs();    
    pre_build();
    for (int i=1;i<=qq;i++)
    {
        scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
        printf("%d\n",spfa());
    }
    return 0;
}