UVA - 12569 Planning mobile robot on Tree (EASY Version) BFS

题意:有一颗n个节点的树,其中一个节点有机器人,指定m个节点有障碍物,指定终点,问最少需要移动多少步才能到达,移动过程中遇到障碍物需要将其移动到空地。

分析:bfs搜索,是每次都对障碍物进行移动,将障碍物移动到空闲地方,如果是机器人移动就需要更新位置。

障碍物位置用二进制储存,方便查找,更新。

# include<iostream>
# include<cstdio>
# include<cmath>
# include<map>
# include<queue>
# include<string>
# include<string.h>
#include<set>
#include<list>
# include<algorithm>
using namespace std;
const int maxn = 1 << 20;
struct node {
	int state, pos, pre, len;
	node(){}
	node(int _state,int _pos,int _pre,int _len):state(_state),pos(_pos),pre(_pre),len(_len){}
};
vector<int>G[20];
node q[maxn];
int vis[20][maxn];
int n, obnum, s, t;
int start,step;
void bfs(int ob) {
	int front = 0, rear = 1;
	node temp(ob, s, -1, 0);
	q[front] = temp;
	vis[s][ob] = 1;
	while (front < rear) {
		node u = q[front];
		if (u.pos == t) {//移动到终点就退出
			start = front;
			step = u.len;
			break;
		}
		for (int i = 0; i < n; i++) {
			if ((1 << i)&u.state) {//找到障碍物位置
				for (int j = 0; j < G[i].size(); j++) {
					int next = G[i][j];
					if ((1 << next)&u.state)continue;//找到空闲位置
					node ttd = u;
					ttd.pos = u.pos; ttd.state = ((u.state|(1<<next))^(1<<i));
					if (ttd.pos == i)ttd.pos = next;//如果是机器人移动,就更新位置
					if (!vis[ttd.pos][ttd.state]) {
						vis[ttd.pos][ttd.state] = 1;
						ttd.len++;
						ttd.pre = front;
						q[rear++] = ttd;
					}
				}
			}
		}
		front++;
	}
}
void result(int u) {
	if (q[u].pre != 0)result(q[u].pre);//从前往后输出
	int last = q[q[u].pre].state;
	int cur = q[u].state;;
	int a, b;
	a = last ^ (last&cur);//因为每次只移动一步
	b = cur ^ (last&cur);
	int aa, bb;
	for (int i = 0; i < n; i++) {
		if ((1 << i)&a)aa = i;
		if ((1 << i)&b)bb = i;
	}
	cout << aa + 1 << " " << bb + 1 << endl;
}
int main() {
	int kase;
	cin >> kase;
	for (int k = 0; k < kase; k++) {
		for (int i = 0; i < 20; i++)G[i].clear();
		memset(vis, 0, sizeof(vis));
		step = -1;
		cin >> n >> obnum >> s >> t;
		int obstacle = 0;
		s--, t--;
		for (int i = 0; i < obnum; i++) { 
			int l;
			cin >> l;
			l--;
			obstacle |= (1<<l);
		}
		for (int i = 0; i < n - 1; i++) { 
			int temp,temp1; cin >> temp>>temp1;
			G[temp-1].push_back(temp1-1);
			G[temp1-1].push_back(temp-1);
		}
		obstacle |= (1 << s);
		bfs(obstacle);
		cout << "Case " << k + 1 << ": ";
		if (step == -1) {
			cout << "-1" << endl;
		}
		else {
			cout << step << endl;
			result(start);
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36973725/article/details/84933674