1. 程式人生 > >UVA - 12569 Planning mobile robot on Tree (EASY Version) BFS

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