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;
}

  

时间: 2024-11-10 18:27:07

UVA-12569 Planning mobile robot on Tree (EASY Version) (BFS+状态压缩)的相关文章

Uva 12569 Planning mobile robot on Tree (EASY Version)

基本思路就是Bfs: 本题的一个关键就是如何判段状态重复. 1.如果将状态用一个int型数组表示,即假设为int state[17],state[0]代表机器人的位置,从1到M从小到大表示障碍物的位置.那么如果直接用STL中的set是会超时的,但如果自己建立一个hash方法,像这样: int getKey(State& s) { long long v = 0; for(int i=0; i<=M; ++i ) { v = v * 10 + s[i]; } return v % hashSi

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

Problem UVA12569-Planning mobile robot on Tree (EASY Version) Accept:138  Submit:686 Time Limit: 3000 mSec  Problem Description  Input The first line contains the number of test cases T (T ≤ 340). Each test case begins with four integers n, m, s, t (

UVA Planning mobile robot on Tree树上的机器人(状态压缩+bfs)

用(x,s)表示一个状态,x表示机器人的位置,s表示其他位置有没有物体.用个fa数组和act数组记录和打印路径,转移的时候判断一下是不是机器人在动. #include<bits/stdc++.h> using namespace std; const int maxn = 16; const int maxe = 32; const int MAXSTA = 491520+10; // 2^15*15 int head[maxn],to[maxe],nxt[maxe]; int ecnt; v

ZOJ 3802 Easy 2048 Again ( 状态压缩 )

题目链接~~> 做题感悟:这题很经典 ,需要模拟一下找规律,还是那句话遇到题自己应该手动推一下. 解题思路: 这题如果手动推几组数据的话就应该发现 ,如果放进队列的元素是递减的话,这样才可以连续合并,如果队列中有 a  ,b , a < b 那么 a 前面的必定不会与 b 经过合并再合并,因为越合并越大,so ~> 队列中最多才存 12 个数,可以用状态压缩压缩一下.注意要用滚动数组,不用可能超时. 代码: #include<iostream> #include<sst

uva 1533(bfs+状态压缩)

题意:有一个棋盘如下,黑色表示有棋子,白色表示空,棋盘初始状态为有一个位置n为空,其他位置都有棋子. 每次可以选择一个棋子在一条直线上隔一个或连续多个棋子跳到空白位置,然后这一个或多个棋子就被拿走,问最少几步可以使棋盘上的棋子拿走到只剩下一个且位置和初始空白位置相同.输出几步和每步的起始与落子位置.输出字典序最小的解,无解输出IMPOSSIBLE. 题解:因为棋盘上有15个位置,可以用状态压缩来表示棋盘的状态,1表示有棋子,0表示空白,每个棋子走的方向有6种,所以用一个flag[i][j]数组表

Codeforces Round #316 (Div. 2) D. Tree Requests(DFS+状态压缩)

题意:给定一棵树,n个节点.每一个节点处有一个字母,结点的深度定义为节点到根结点1的距离, 有m个询问(u.v),每次回答以结点u为根的子树的深度为v的那些节点处的字母是否能组成一个回文串,特别的,空串也是回文串. 思路:首先说明推断回文串的方法,仅仅要出现次数为奇数个字母个数不超过2.那么这些字母一定能够组成回文串. 接下来考虑将树转成线性结构. 利用dfs+时间戳将结点依照深度存入一个线性结构里,Depth[i]数组里存的是深度为i的全部结点, 那么对于询问有三种情况.一种是dep[u]>=

Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given an undirected tree of nn vertices. Some vert

UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)

题目链接:UVA 811 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been gathered by his ancestors on their travels. To protect his trees from thieves, the king or

uva 11195 Another queen (用状态压缩解决N后问题)

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2136 Problem A Another n-Queen Problem I guess the n-queen problem is known by every person who has studied backtracking. In this problem you s