首先输入三个数字 r ,d ,s r代表房间的数量,d代表门的数量,也就是房间连通的数量,s代表开关的数量。然后接下去 d + s 行是门和开关的描述。
题目的意思是这样的,有r个房间,每个房间的开关可以控制其它房间的灯,你只能走灯亮的房间,然后要走到第r个房间,并且其它房间灯都暗的。你现在在房间1 并且房间1灯是亮的,要求几个步骤可以到达这种状态,状态改变可以是 开灯,关灯,走到其它房间。
首先我们一个数组保存状态,数组第一个位置代表现在所处的房间,接下去用‘0’ ‘1’ 表示每个房间的灯是开还是关,用map <string ,int>判重。
然后就是bfs()把每一种状态入队列;
有一点要注意,就是这题最后要把所有步骤输出,所以我把记录步骤分成两部分,第一部分开灯关灯还是移动,分别用1,2,3,
AC代码:
#include <stdio.h>
#include <string.h>
#include <string>
#include <queue>
#include <map>
using namespace std;
const int N = 15 + 5;
int r, d, s;
bool ok;
char tar[N];
int link[N][N], swlink[N][N];
struct state {
char s[N];
int step[10005];
int stepnum;
int room;
} st,st1;
map<string, int> vis;
queue<state> q;
void bfs() {
ok = false;
vis.clear();
while (!q.empty()) {
q.pop();
}
st.room = 1;
st.s[0] = '1';
st.s[1] = '1';
for (int i = 2; i <= r; i ++) {
st.s[i] = '0';
}
st.s[r + 1] = '\0';
st.stepnum = 0;
vis[st.s] = 1;
q.push(st);
while (!q.empty()) {
st = q.front();
if (strcmp(st.s,tar) == 0) {
ok = true;
return;
}
q.pop();
for (int i = 1; i <= r; i++) {
st1 = st;
if (link[st1.room][i] && st1.s[i] == '1') {
st1.s[0] = i + '0';
if (!vis[st1.s]) {
vis[st1.s] = 1;
st1.room = i;
st1.step[st1.stepnum ++] = 3;
st1.step[st1.stepnum ++] = i;
q.push(st1);
}
}
st1 = st;
if (swlink[st1.room][i] && i != st1.room) {
if (st1.s[i] == '1') {
st1.s[i] = '0';
st1.step[st1.stepnum ++] = 2;
st1.step[st1.stepnum ++] = i;
}
else {
st1.s[i] = '1';
st1.step[st1.stepnum ++] = 1;
st1.step[st1.stepnum ++] = i;
}
if (!vis[st1.s]) {
vis[st1.s] = 1;
q.push(st1);
}
}
}
}
}
int main() {
int t = 1;
while (scanf("%d%d%d", &r, &d, &s) != EOF && (r + d + s)) {
int temp, temp2;
memset(link, 0, sizeof(link));
memset(swlink, 0, sizeof(swlink));
tar[0] = r + '0';
tar[r] = '1';
tar[r + 1] = '\0';
for (int i = 1; i < r; i ++)
tar[i] = '0';
for (int i = 0; i < d; i ++) {
scanf("%d%d", &temp, &temp2);
link[temp][temp2] = link[temp2][temp] = 1;
}
for (int i = 0; i < s; i ++) {
scanf("%d%d", &temp, &temp2);
swlink[temp][temp2] = 1;
}
bfs();
printf("Villa #%d\n", t ++);
if (ok) {
printf("The problem can be solved in %d steps:\n", (st.stepnum + 1) / 2);
for (int i = 0; i < st.stepnum; i ++) {
if (i % 2 == 0) {
if (st.step[i] == 1)
printf("- Switch on light in room ");
if (st.step[i] == 2)
printf("- Switch off light in room ");
if (st.step[i] == 3)
printf("- Move to room ");
}
if (i % 2) {
printf("%d.\n", st.step[i]);
}
}
}
else
printf("The problem cannot be solved.\n");
printf("\n");
}
return 0;
}