icpc live archive6455(状压搜索)

https://icpcarchive.ecs.baylor.edu/external/64/6455.pdf

题意:求从起点走遍所有k个点所需的中最小步数,算是状态压缩搜索的经典题目了。

分析:状态即为已走过点的情况,一个int型可以搞定。有一个小技巧,一般状态压缩的题目主要的属性一般不超过32或64个点

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<set>
#include<cstring>
#include<algorithm>
#define LL long long
#define MOD 100000007
#define INF 0x3f3f3f3f
using namespace std;

const int maxn=105;
char g[maxn][maxn];
int opp[maxn][maxn];
bool done[maxn][maxn][16];
int n,m,k,sx,sy;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};

struct node
{
    int x,y,w,key;
    node(int xx=0,int yy=0,int ww=0,int cc=0)
    {
        x=xx;y=yy;w=ww;key=cc;
    }
};

bool is_ill(int x,int y)
{
    return x<0||x>=n||y<0||y>=m;
}
int bfs()
{
    queue<node>q;
    memset(done,0,sizeof done);
    q.push(node(sx,sy,0,k));
    done[sx][sy][k]=1;
    while(!q.empty())
    {
        node x=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            int curx=x.x+dx[i];
            int cury=x.y+dy[i];
            int curkey=x.key;
            if(is_ill(curx,cury)||g[curx][cury]=='#')continue;
            if(opp[curx][cury]==-1&&done[curx][cury][curkey])continue;
            if(x.key&(1<<opp[curx][cury]))curkey^=(1<<opp[curx][cury]);
            if(done[curx][cury][curkey])continue;
            if(curkey==0)return x.w+1;
            q.push(node(curx,cury,x.w+1,curkey));
            done[curx][cury][curkey]=1;
            //printf("%d %d %d %d\n",curx,cury,x.w+1,curkey);
        }
    }
    return -1;
}
int main()
{
    int a,b,kk;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        for(int i=0;i<n;i++)
            scanf("%s",g[i]);
        scanf("%d",&kk);
        if(kk==0)
        {
            printf("0\n");
            continue;
        }
        int aa=0;k=0;
        memset(opp,-1,sizeof opp);
        for(int i=0;i<kk;i++)
            scanf("%d%d",&a,&b),a--,b--,k|=(1<<i),opp[a][b]=i;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            if(g[i][j]=='@')sx=i,sy=j;

        printf("%d\n",bfs());
    }
    return 0;
}


你可能感兴趣的:(icpc live archive6455(状压搜索))