12569 - Planning mobile robot on Tree (EASY Version)

来源:互联网 发布:电缆标识球数据 编辑:程序博客网 时间:2024/05/17 01:42

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

我有话说:
这是一道bfs。因为他要移动每一个石头或者机器人。换成dfs的话,一个是不知道目标状态(最小步数),二是容易爆栈。既然是bfs,那么要考虑一下如何判重,想法是转换成二进制,对于编号上的格子是否有石头或者机器人采用1或0表示。但是,数组开太小会RE太大会TLE,后来看了一个大神的题解,选择了一个恰好的maxstate。

#include <iostream>#include <cstdio>#include <vector>#include <queue>#include <algorithm>#include <cstring>using namespace std;struct State{   int robot,tree,d;   int x,y;};const int maxstate=(1<<15)*15+10;int T,n,m,s,t,kase=1,init_tree,vis[1<<15][15];vector<int>G[20];State st[maxstate];int fa[maxstate];void Init(){    scanf("%d%d%d%d",&n,&m,&s,&t);    memset(vis,0,sizeof(vis));    memset(fa,0,sizeof(fa));    for(int i=0;i<20;i++)G[i].clear();    init_tree=0;//清空变量    s--;t--;    for(int i=0;i<m;i++)    {        int stone;        scanf("%d",&stone);        init_tree|=(1<<(stone-1));//节省空间,全部-1    }    init_tree|=(1<<s);    int a,b;    for(int i=0;i<n-1;i++)    {        scanf("%d%d",&a,&b);        G[a-1].push_back(b-1);        G[b-1].push_back(a-1);    }}void print(int ans){     if(fa[ans])print(fa[ans]);     printf("%d %d\n",st[ans].x+1,st[ans].y+1);}int solve(){     int front=0,rear=1;     State& start=st[front];     start.d=0;     start.robot=s;     start.tree=init_tree;     start.x=start.y=0;     fa[front]=-1;     while(front<rear)     {         State& u=st[front];         if(u.robot==t){// 得解            printf("%d\n",u.d);            print(front);            return 1;         }         for(int i=0;i<n;i++)if(u.tree&(1<<i))//有机器人或石头            for(int j=0;j<G[i].size();j++){                if(u.tree&(1<<G[i][j]))continue;//有障碍                State& v=st[rear];                v.d=u.d+1;                v.robot=u.robot;                v.tree=u.tree-(1<<i)+(1<<G[i][j]);//移动                if(i==u.robot)v.robot=G[i][j];                if(vis[v.tree][v.robot])continue;                vis[v.tree][v.robot]=1;                fa[rear]=front;                v.x=i;                v.y=G[i][j];                rear++;            }        front++;     }     printf("-1\n");     return 0;}int main(){    scanf("%d",&T);    while(T--)    {        Init();        printf("Case %d: ",kase++);        solve();        printf("\n");    }    return 0;}
0 0