UVA-12569 Planning mobile robot on Tree (EASY Version) (BFS+状态压缩)

题目大意:一张无向连通图,有一个机器人,若干个石头,每次移动只能移向相连的节点,并且一个节点上只能有一样且一个东西(机器人或石头),找出一种使机器人从指定位置到另一个指定位置的最小步数方案,输出移动步骤。

题目分析:以机器人的所在位置和石头所在位置集合标记状态,状态数最多有15*2^15个。广搜之。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<string>
# include<queue>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;

struct Edge
{
    int to,nxt;
};

struct node
{
    int t,u,sta;
    string path;
    node(int _t,int _u,int _s,string _p):t(_t),u(_u),sta(_s),path(_p){}
    bool operator < (const node &a) const {
        return t>a.t;
    }
};
Edge e[32];
int n,cnt,head[16],vis[15][1<<15];

void add(int u,int v)
{
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}
void bfs(int s,int st,int ed)
{
    priority_queue<node>q;
    memset(vis,0,sizeof(vis));
    vis[s][st]=1;
    q.push(node(0,s,st,""));
    while(!q.empty())
    {
        node u=q.top();
        q.pop();
        if(u.u==ed){
            printf("%d\n",u.t);
            for(int i=0;i<u.path.size();i+=2)
                printf("%d %d\n",u.path[i]-'A'+1,u.path[i+1]-'A'+1);
            return ;
        }
        for(int i=0;i<n;++i){
            if(u.sta&(1<<i)){
                for(int j=head[i];j!=-1;j=e[j].nxt){
                    int v=e[j].to;
                    if(u.sta&(1<<v))
                        continue;
                    if(v==u.u)
                        continue;
                    int ns=u.sta^(1<<i);
                    ns|=(1<<v);
                    if(!vis[u.u][ns]){
                        vis[u.u][ns]=1;
                        string p=u.path;
                        p+=(char)(i+'A'),p+=(char)(v+'A');
                        q.push(node(u.t+1,u.u,ns,p));
                    }
                }
            }
        }
        for(int i=head[u.u];i!=-1;i=e[i].nxt)
        {
            int v=e[i].to;
            if(u.sta&(1<<v))
                continue;
            if(!vis[v][u.sta]){
                vis[v][u.sta]=1;
                string p=u.path;
                p+=(char)(u.u+'A'),p+=(char)(v+'A');
                q.push(node(u.t+1,v,u.sta,p));
            }
        }
    }
    printf("-1\n");
}
int main()
{
    int T,a,b,s,t,st,m,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        st=cnt=0;
        memset(head,-1,sizeof(head));
        scanf("%d%d%d%d",&n,&m,&s,&t);
        --s,--t;

        while(m--)
        {
            scanf("%d",&a);
            st|=(1<<(a-1));
        }
        for(int i=1;i<n;++i){
            scanf("%d%d",&a,&b);
            add(a-1,b-1);
            add(b-1,a-1);
        }
        printf("Case %d: ",++cas);
        bfs(s,st,t);
        if(T)
            printf("\n");
    }
    return 0;
}

  

posted @ 2015-09-21 15:38  20143605  阅读(223)  评论(0编辑  收藏  举报