题目大意:别墅里面有r间房间,d扇门,s个开关,最初的状态是:房间1的灯是开着的,其他的灯都是关着的。现在有一个人在房间1,这个人怕黑,所以要待在一个房间或者要去另一个房间的条件是,这个房间的灯必须是开的,现在给出最终状态,最终状态是:这个人到了房间r,除了房间r的灯是亮的外,其他房间的灯都是灭的,求最少的操作数。(每到另一个房间,或者开关一个房间的灯都是一个操作)
解题思路:因为房间最多只有十个,且每个房间的灯只有两种状态,不是开就是关,所以可以用二进制表示形式将所有房间的状态记录下来,接着进行BFS即可
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 15
#define maxm 60000
struct Status{
int pos, s, time, pre;
int beha;
int des;
};
Status Sta[maxm];
int R, D, S;
int door[maxn][maxn],key[maxn][maxn];
int vis[maxm][maxn],last, end;
bool flag;
int try_insert(int cur) {
int s = Sta[cur].s;
int p = Sta[cur].pos;
if(vis[s][p])
return false;
vis[s][p] = 1;
return true;
}
void BFS() {
Sta[0].pos = 1;
Sta[0].s = 2;
Sta[0].time = 0;
Sta[0].pre = 0;
int front = 0, rear = 1;
while(front < rear) {
Status &t = Sta[front];
int p = t.pos;
int s = t.s;
int tim = t.time;
if( p == R && s == last ) {
end = front;
flag = true;
break;
}
for(int i = 1; i <= R; i++)
if(key[p][i] && i != p) {
int st = s ^ (1 << i);
Sta[rear].pos = p;
Sta[rear].s = st;
Sta[rear].time = tim + 1;
Sta[rear].pre = front;
if( (s >> i) % 2 == 0)
Sta[rear].beha = 1;
else
Sta[rear].beha = 3;
Sta[rear].des = i;
if(try_insert(rear))
rear++;
}
for(int i = 1; i <= R; i++)
if( door[p][i] && (s & (1 << i)) ) {
Sta[rear].pos = i;
Sta[rear].s = s;
Sta[rear].time = tim + 1;
Sta[rear].pre = front;
Sta[rear].beha = 2;
Sta[rear].des = i;
if(try_insert(rear))
rear++;
}
front++;
}
}
void print_path(int cur) {
if(cur == 0)
return ;
print_path(Sta[cur].pre);
if(Sta[cur].beha == 1)
printf("- Switch on light in room %d.\n",Sta[cur].des);
if(Sta[cur].beha == 2)
printf("- Move to room %d.\n",Sta[cur].des);
if(Sta[cur].beha == 3)
printf("- Switch off light in room %d.\n",Sta[cur].des);
}
int main() {
int mark = 1;
while(scanf("%d%d%d",&R, &D ,&S) != EOF && R + D + S) {
int t1, t2;
memset(door,0,sizeof(door));
memset(key,0,sizeof(key));
memset(vis,0,sizeof(vis));
for(int i = 0; i < D; i++) {
scanf("%d%d",&t1,&t2);
door[t1][t2] = door[t2][t1] = 1;
}
for(int i = 0; i < S; i++) {
scanf("%d%d",&t1,&t2);
key[t1][t2] = 1;
}
last = 1 << R;
flag = false;
BFS();
printf("Villa #%d\n",mark++);
if(flag){
printf("The problem can be solved in %d steps:\n",Sta[end].time);
print_path(end);
}
else
printf("The problem cannot be solved.\n");
printf("\n");
}
return 0;
}