※NC17872 CSL的校园卡

二路\(BFS\)

  • 用二进制来表示地图的遍历状态
  • \(dist\)起到距离和判重两重作用,故\(dist\)数组也要加上二进制状态这一维
const int N=5;
struct Node
{
    int x1,y1;
    int x2,y2;
    int s;
};
char g[N][N];
int dist[N][N][N][N][1<<16];
PII st;
int n,m;

inline bool check(int x,int y)
{
    return x>=0 && x<n && y>=0 && y<m;
}

int bfs(int x,int y,int state)
{
    memset(dist,-1,sizeof dist);
    queue<Node> q;
    q.push({x,y,x,y,state});
    dist[x][y][x][y][state]=0;

    while(q.size())
    {
        Node t=q.front();
        q.pop();

        int x1=t.x1,y1=t.y1,x2=t.x2,y2=t.y2,s=t.s;
        if(s == (1<<(n*m))-1) return dist[x1][y1][x2][y2][s];

        for(int i=0;i<4;i++)
        {
            int a=x1+dx[i],b=y1+dy[i];
            if(!check(a,b) || g[a][b] == 'X') continue;

            for(int j=0;j<4;j++)
            {
                int c=x2+dx[j],d=y2+dy[j];
                if(!check(c,d) || g[c][d] == 'X') continue;
                int ns=s|(1<<(a*m+b))|(1<<(c*m+d));
                if(dist[a][b][c][d][ns] == -1)
                {
                    dist[a][b][c][d][ns]=dist[x1][y1][x2][y2][s]+1;
                    q.push({a,b,c,d,ns});
                }
            }
        }
    }
    return -1;
}

int main()
{
    cin>>n>>m;

    int state=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            scanf(" %c",&g[i][j]);
            if(g[i][j] == 'S') st={i,j},state|=(1<<(i*m+j));
            if(g[i][j] == 'X') state|=1<<(i*m+j);
        }

    int t=bfs(st.fi,st.se,state);
    cout<<t<<endl;

    //system("pause");
}
posted @ 2020-09-30 12:03  Dazzling!  阅读(126)  评论(0编辑  收藏  举报