Planning mobile robot on Tree (EASY Version) UVA

来源:互联网 发布:java bigdecimal最大值 编辑:程序博客网 时间:2024/05/16 14:59

有一定难度的一道题目,利用移位操作来对每一个节点的状态进行记录,如果该节点所在的那位为1,说明该节点中是存在机器人/障碍物的,如果为0,则表示没有,同时为了操作的统一性,我们的节点从0开始编号,也就是说,对于输入中的每个节点的编号都要减一。然后利用队列来模拟bfs搜索。定义一个新的数据结构node,node中的state用来记录现在的树中的节点的状态(需要移位操作计算出结果),同时length记录的是移动的操作次数,pre是后面用来递归打印操作的路径所用的,也就是记录的是前一个点的下标。pos用来记录当前的机器人所在的节点的位置。首先队列中放入初始的点,也就是机器人的位置pos在s中,同时pre为-1,length为0,state为初始计算出来的start。然后每次判断如果队列不为空,那么取出队列头的节点,首先判断机器人是否已经到了目标的位置,如果到达,那么记录最终状态对应的节点,结束循环,如果没有到达,那么继续后续操作。依次判断每一个节点在当前的状态下是否存在障碍物或者是机器人,如果存在,那么遍历和当前节点相邻的节点,如果相邻的节点是没有障碍物的(包括机器人在内),那么就将当前已经存在的某个节点中的障碍物转移道现在的空闲的节点中,这里要注意一个问题,如果转移的是机器人,那么需要更新机器人的位置的信息。然后判断目前的状态之前是否监测过,如果没有监测过,那么将当前的节点放置到队列当中,继续后面的循环操作即可,最后判断,必要的时候递归打印就行了,具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;const int maxn = 1 << 20;class node{public:int state,pos,pre,length;void set(int _state,int _pos,int _pre,int _length){state = _state, pos = _pos, pre = _pre, length = _length;}};node q[maxn];vector<int> G[20];int visit[20][maxn];int T, n, m, s, t;void getRes(int ind){if (q[ind].pre != 0) getRes(q[ind].pre);int from_s = q[q[ind].pre].state;int to_s = q[ind].state;int a, b;a = from_s ^ (from_s&to_s);b = to_s ^ (from_s&to_s);int u, k;for (int i = 0; i < n; i++){if ((1 << i)&a) u = i;if ((1 << i)&b) k = i;}cout << u+1 << " " << k+1 << endl;}int main(){cin >> T;memset(visit, 0, sizeof(visit));for (int i = 1; i <= T; i++){cin >> n >> m >> s >> t;for (int j = 0; j < n; j++) G[j].clear();s--, t--;int start = 0;for (int j = 0; j < m; j++){int t2;cin >> t2;t2--;start = start | (1 << t2);}for (int j = 0; j < n - 1; j++){int a, b;cin >> a >> b;a--, b--;G[a].push_back(b);G[b].push_back(a);}start |= (1 << s);int front = 0, rear = 1;q[front].set(start, s, -1,0);visit[s][start] = i;node ok;ok.set(0, 0, -1, -1);while (front < rear){node temp = q[front];if (temp.pos == t){ok = temp;break;}for (int ind = 0; ind < n; ind++){if ((1 << ind) & temp.state){for (int ind2 = 0; ind2 < G[ind].size(); ind2++){int ind3 = G[ind][ind2];if ((1 << ind3) & temp.state) continue;int pos = temp.pos, state2 = ((temp.state | (1 << ind3)) ^ (1 << ind));if (pos == ind) pos = ind3;if (visit[pos][state2]!= i){visit[pos][state2] = i;q[rear++].set(state2, pos, front, temp.length + 1);}}}}front++;}cout << "Case " << i << ": ";if (ok.length == -1){cout << "-1\n";}else{cout << ok.length << endl;getRes(front);}cout << endl;}return 0;}