没什么难得。。。拿一个结构题储存每一步的状态就行了。。。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXD 10 + 5
#define MAX_SIZE 10000 + 10
int G[MAXD][MAXD]; /*房间的连通状态*/
int L[MAXD][MAXD]; /*表示i可以控制j房间的灯*/
struct State{
int pos; /*当前所在的房间*/
int light[MAXD]; /*当前每个房间里面灯的状态代表开,0代表关*/
int rote[MAX_SIZE]; /*路线*/
int step;/*步数*/
}st[MAX_SIZE];
int r,d,s;
int front , back ;
bool Compare(State p){
for(int i = 1; i < back ;i++)
if(st[i].pos == p.pos && !memcmp(p.light,st[i].light,sizeof(st[i].light)))
return false;
return true;
}
bool Judge_ok(int pos,int light[]){
if(pos != r)
return false;
for(int i = 1;i < r;i++)
if(light[i] != 0)
return false;
return true;
}
void solve(){
front = 0; back = 0;
st[back].pos = 1;
memset(st[back].light,0,sizeof(st[back].light));
st[back].light[1] = 1;
st[back].step = 0;
back++;
while(front < back){
int pos = st[front].pos;
int light[MAXD];
int step = st[front].step;
int rote[MAX_SIZE];
memcpy(rote ,st[front].rote ,sizeof(st[front].rote));
memcpy(light,st[front].light,sizeof(st[front].light));
/*在一个房间可以有2个动作,一个是走到下一个房间,另外一个是开灯*/
/*先考虑走路*/
if(Judge_ok(pos,light)){
printf("The problem can be solved in %d steps:\n",step);
for(int i = 0 ; i < step ;i++)
if(rote[i] <= 10)
printf("- Move to room %d.\n",rote[i]);
else if(rote[i] <30)
printf("- Switch on light in room %d.\n",rote[i]-15);
else
printf("- Switch off light in room %d.\n",rote[i]-30);
return ;
}
for(int i = 1;i <= r; i++)
if(G[pos][i] == 1 && light[i] == 1) /*如果房间是连通的,并且房子开着灯*/{
memcpy(st[back].light,light,sizeof(light));
memcpy(st[back].rote,rote,sizeof(rote));
st[back].step = step;
st[back].pos = i;
st[back].rote[st[back].step++] = i;
if(Compare(st[back]))
back++;
}
/*再考虑是否开灯关灯*/
for(int i = 1;i <= r; i++)
if(L[pos][i] && pos != i){ /*如果这个房间可以打开另一个房间的灯*/
memcpy(st[back].light,light,sizeof(light));
memcpy(st[back].rote,rote,sizeof(rote));
if(st[back].light[i] == 0) st[back].light[i] = 1;
else if(st[back].light[i] == 1) st[back].light[i] = 0;
st[back].pos = pos;
st[back].step = step;
if(st[back].light[i] == 1)
st[back].rote[st[back].step++] = i + 15;
else
st[back].rote[st[back].step++] = i + 30;
/* +15代表是开灯操作*/
if(Compare(st[back]))
back++;
}
front++;
}
printf("The problem cannot be solved.\n");
return ;
}
int main(){
int Case = 1;
while(scanf("%d%d%d",&r,&d,&s)){
if(!r && !d && !s) break;
memset(G,0,sizeof(G));
memset(L,0,sizeof(L));
for(int i = 0 ; i < d ; i++){
int x,y;
scanf("%d%d",&x,&y);
G[x][y] = G[y][x] = 1;
}
for(int i = 0; i < s;i++){
int x,y;
scanf("%d%d",&x,&y);
L[x][y] = 1;
}
printf("Villa #%d\n",Case++);
solve();
printf("\n");
}
return 0;
}