zoj 1301 The New Villa

bfs题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int r, d, s;
int conn[11][11], sw[11][11];
int vis[1 << 11][11];
int bi[12];
vector<string> ans;
struct node {
	int state;
	int cur;
	vector<string> route;
};

void build() {
	bi[1] = 1;
	for (int i = 2; i <= 11; i++) {
		bi[i] = bi[i - 1] << 1;
	}
}

void inti() {
	memset(conn, 0, sizeof(conn));
	memset(sw, 0, sizeof(sw));
	memset(vis, 0, sizeof(vis));
	ans.clear();
}

string getstr(int x) {
	string str = "";
	while (x) {
		str = char('0' + x % 10) + str;
		x /= 10;
	}
	str += '.';
	return str;
}

bool bfs() {
	queue<node> q;
	vector<string> v;
	node start = {bi[1], 1, v};
	vis[start.state][start.cur] = 1;
	q.push(start);
	int x, i, cur, state, t;
	while (!q.empty()) {
		x = q.size();
		for (i = 0; i < x; i++) {
			node nd = q.front();
			q.pop();
			cur = nd.cur;
			state = nd.state;

			if (state == bi[r] && cur == r) {
				ans = nd.route;
				return true;
			}

			//move
			for (i = 1; i <= r; i++) {
				if (i == cur)continue;
				if (conn[cur][i] && (state & bi[i]) && !vis[state][i]) {//灯要亮着 然后这种情况还没有被访问过
					vis[state][i] = 1;
					node nnd = {state, i, nd.route};
					string str = "- Move to room ";
					str += getstr(i);
					nnd.route.push_back(str);
					q.push(nnd);
				}
			}

			//switch on
			for (i = 1; i <= r; i++) {
				if (i == cur)continue;
				if (sw[cur][i] && !(state & bi[i]) && !vis[state | bi[i]][cur]) {
					vis[state | bi[i]][cur] = 1;
					node nnd = {state | bi[i], cur, nd.route};
					string str = "- Switch on light in room ";
					str += getstr(i);
					nnd.route.push_back(str);
					q.push(nnd);
				}
			}

			//switch off
			for (i = 1; i <= r; i++) {
				if (i == cur)continue;
				if (sw[cur][i] && (state & bi[i])) {
					t = ~bi[i];
					t = (bi[11] - 1) & t;
					t = state & t;
					if (!vis[t][cur]) {
						vis[t][cur] = 1;
						node nnd = {t, cur, nd.route};
						string str = "- Switch off light in room ";
						str += getstr(i);
						nnd.route.push_back(str);
						q.push(nnd);
					}
				}
			}
		}
	}
	return false;
}

int main() {
	int i, a, b;
	build();
	int coun = 0;
	while (scanf("%d%d%d", &r, &d, &s) && r)	{
		inti();
		for (i = 0; i < d; i++) {
			scanf("%d%d", &a, &b);
			conn[a][b] = 1;
			conn[b][a] = 1;
		}

		for (i = 0; i < s; i++) {
			scanf("%d%d", &a, &b);
			sw[a][b] = 1;
		}

		printf("Villa #%d\n", ++coun);

		if (bfs()) {
			printf("The problem can be solved in %d steps:\n", ans.size());
			for (i = 0; i < ans.size(); i++) {
				cout << ans[i] << endl;
			}
		} else {
			printf("The problem cannot be solved.\n");
		}

		printf("\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值