初看这道题,想到纯暴力bfs , 但是套一个并查集优化 -1 的情况

但是要特判 出发点 与 目的点 重合的情况!!!!!! (score 10)

TLE&WA 代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smin(x,tmp) x=min(x,tmp)
#define smax(x,tmp) x=max(x,tmp)
const int maxn=35;
const int INF=0x3f3f3f3f;
const int dx[]={0,-1,0,1,0};
const int dy[]={0,0,-1,0,1};//u l d r
int n,m,q;
int g[maxn][maxn];
struct Coord
{
    int x,y;
    bool operator == (const Coord t)const
    {
        return x==t.x&&y==t.y;
    }
};
Coord fa[maxn][maxn];
Coord find(int x,int y)
{
    if(fa[x][y]==(Coord){x,y}) return fa[x][y];
    else return fa[x][y]=find(fa[x][y].x,fa[x][y].y);
}
inline bool union_find(int x,int y,int i,int j)
{
    Coord t1=find(x,y),t2=find(i,j);
    if(t1==t2) return false;
    fa[t2.x][t2.y]=t1;
    return true;
}
inline void init()
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                    scanf("%d",&g[i][j]),fa[i][j]=(Coord){i,j};
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
                for(int d=1;d<=2;d++)
                {
                    int x=i+dx[d],y=j+dy[d];
                    union_find(x,y,i,j);
                }
}
struct Status
{
    int ei,ej;
    int ci,cj;
    Status (const int e1,const int e2,const int c1,const int c2)
    {
        ei=e1,ej=e2;
        ci=c1,cj=c2;
    }
    bool check(int di,int dj)
    {
        return ci==di && cj==dj;
    }
    bool operator < (const Status t) const
    {
        if(ei^t.ei) return ei<t.ei;
        if(ej^t.ej) return ej<t.ej;
        if(ci^t.ci) return ci<t.ci;
        return cj<t.cj;
    }
};
int f[maxn][maxn][maxn][maxn];//no need to use map!!
int bfs(Status S,int di,int dj)
{
    if(S.ei == di && S.ej == dj) return 0;// must judge here!! same node!!
    queue <Status> que;
    que.push(S);f[S.ei][S.ej][S.ci][S.cj]=0;
    while(!que.empty())
    {
        Status u=que.front();que.pop();
        int x0=u.ei,y0=u.ej;
        for(int i=1;i<=4;i++)
        {
            int x=x0+dx[i],y=y0+dy[i];
            if(!g[x][y]) continue;
            Status v=u;
            v.ei=x,v.ej=y;
            if(x==v.ci && y==v.cj) v.ci=u.ei,v.cj=u.ej;
            int cost=f[u.ei][u.ej][u.ci][u.cj]+1;
            if(v.check(di,dj)) return cost;
            if(!f[v.ei][v.ej][v.ci][v.cj] || f[v.ei][v.ej][v.ci][v.cj]>cost) f[v.ei][v.ej][v.ci][v.cj]=cost,que.push(v);
        }
    }
    return -1;
}
int main()
{
    freopen("puzzle.in","r",stdin);
    freopen("puzzle.out","w",stdout);
    init();
    while(q--)
    {
        int e1,e2,c1,c2,d1,d2;
        scanf("%d%d%d%d%d%d",&e1,&e2,&c1,&c2,&d1,&d2);
        if(find(e1,e2)==find(d1,d2)&&find(d1,d2)==find(c1,c2)) printf("%d\n",bfs(Status(e1,e2,c1,c2),d1,d2));
        else printf("-1\n");
        memset(f,0,sizeof(f));
    }
    return 0;
}
View Code

相关文章: