uva 321 - The New Villa

来源:互联网 发布:linux 内核 内存管理 编辑:程序博客网 时间:2024/05/17 06:36
 The New Villa 

Mr. Black recently bought a villa in the countryside. Only one thing bothers him: although there are light switches in most rooms, the lights they control are often in other rooms than the switches themselves. While his estate agent saw this as a feature, Mr. Black has come to believe that the electricians were a bit absent-minded (to put it mildly) when they connected the switches to the outlets.

One night, Mr. Black came home late. While standing in the hallway, he noted that the lights in all other rooms were switched off. Unfortunately, Mr. Black was afraid of the dark, so he never dared to enter a room that had its lights out and would never switch off the lights of the room he was in.

After some thought, Mr. Black was able to use the incorrectly wired light switches to his advantage. He managed to get to his bedroom and to switch off all lights except for the one in the bedroom.

You are to write a program that, given a description of a villa, determines how to get from the hallway to the bedroom if only the hallway light is initially switched on. You may never enter a dark room, and after the last move, all lights except for the one in the bedroom must be switched off. If there are several paths to the bedroom, you have to find the one which uses the smallest number of steps, where ``move from one room to another'', ``switch on a light'' and ``switch off a light'' each count as one step.

Input

The input file contains several villa descriptions. Each villa starts with a line containing three integersr, d, and s. r is the number of rooms in the villa, which will be at most 10.d is the number of doors/connections between the rooms and s is the number of light switches in the villa. The rooms are numbered from 1 tor; room number 1 is the hallway, room number r is the bedroom.

This line is followed by d lines containing two integers i andj each, specifying that room i is connected to room j by a door. Then follows lines containing two integers k and l each, indicating that there is a light switch in roomk that controls the light in room l.

A blank line separates the villa description from the next one. The input file ends with a villa havingr = d = s = 0, which should not be processed.

Output

For each villa, first output the number of the test case (`Villa #1',`Villa #2', etc.) in a line of its own.

If there is a solution to Mr. Black's problem, output the shortest possible sequence of steps that leads him to his bedroom and only leaves the bedroom light switched on. (Output only one shortest sequence if you find more than one.) Adhere to the output format shown in the sample below.

If there is no solution, output a line containing the statement `The problem cannot be solved.'

Output a blank line after each test case.

Sample Input

3 3 41 21 33 21 21 32 13 22 1 22 11 11 20 0 0

Sample Output

Villa #1The problem can be solved in 6 steps:- Switch on light in room 2.- Switch on light in room 3.- Move to room 2.- Switch off light in room 1.- Move to room 3.- Switch off light in room 2.Villa #2The problem cannot be solved.

        有r个房间,房间1是走廊,房间r是卧室,每个房间有开关(可能有多个)控制其他房间的灯,初始的时候人在走廊(房间1)只有走廊灯亮着,目标状态是卧室(房间r)且只有卧室灯亮着,求最少的步骤数到达目标状态
       明显的BFS+hash判重,状态参量:当前所在房间号码和所有房间灯的亮灭状况,最多十个房间,房间号*10^5+2^10;表示每种不同的状态

      当前在room x,每次操作可以按下room x的某个开关(room x的灯不能关),走到room y(room y的灯亮着·);每次哈希判重;还要输出操作步骤,所以要记录父节点的信息

  

#include<string.h>#include<stdio.h>struct node{ int room,light[11],succ,move,on,off,Light;}q[100000];int top,tail,r,s,d,Map[11][11],Switch[11][11],visit[102049],    exp[11]={1,2,4,8,16,32,64,128,256,512,1024},f;int hash(int num)//每个状态对应一个数字{ int i,key=q[num].room*10000; for (i=1;i<=r;i++) if (q[num].light[i]==1) key+=exp[i]; return key;}void bfs(){ int i,j,k; if (hash(top)==exp[r]+r*10000) {f=1; return ;} for (i=1;i<=r;i++) {  if ((Switch[q[top].room][i])&&(i!=q[top].room))//按开关  {   ++tail;   for (j=1;j<=r;j++)   q[tail].light[j]=q[top].light[j];   q[tail].light[i]=-q[tail].light[i];   q[tail].room=q[top].room;   k=hash(tail);   if (visit[k]) --tail;   else    {     q[tail].move=0;     q[tail].Light=i;     q[tail].on=1; q[tail].off=0;     if (q[top].light[i]==1) {q[tail].on=0;q[tail].off=1;}     visit[k]=1;     q[tail].succ=top;    }  } } for (i=1;i<=r;i++) {  if ((Map[q[top].room][i])&&(q[top].light[i]==1))//走到某个房间;  {   ++tail;   for (j=1;j<=r;j++)   q[tail].light[j]=q[top].light[j];   q[tail].room=i;   k=hash(tail);   if (visit[k]) --tail;    else      {       visit[k]=1;       q[tail].succ=top;       q[tail].move=1;       q[tail].on=0;       q[tail].off=0;      }  } } ++top; if (top<=tail) bfs();};int main(){  int x,y,i,j,a[1000],sum,t=0;  while (scanf("%d%d%d",&r,&s,&d),r+s+d)  {   memset(Map,0,sizeof(Map));   memset(Switch,0,sizeof(Switch));   memset(visit,0,sizeof(visit));   while (s--)   {    scanf("%d%d",&x,&y);    Map[x][y]=1; Map[y][x]=1;   }  for (i=1;i<=d;i++)  {   scanf("%d%d",&x,&y);   Switch[x][y]=1;  }  q[0].room=1;  for (i=2;i<=r;i++)  q[0].light[i]=-1;  q[0].light[1]=1;  top=0; tail=0; visit[hash(0)]=1;  f=0;  bfs();  sum=0;  printf("Villa #%d\n",++t);  if (f)  {   while (top!=0)   {    a[++sum]=top;    top=q[top].succ;   }   printf("The problem can be solved in %d steps:\n",sum);   for (i=sum;i>=1;i--)   {    if (q[a[i]].move==1) printf("- Move to room %d.\n",q[a[i]].room);    if (q[a[i]].on==1)  printf("- Switch on light in room %d.\n",q[a[i]].Light);    if (q[a[i]].off==1) printf("- Switch off light in room %d.\n",q[a[i]].Light);   }  }  else  printf("The problem cannot be solved.\n");   printf("\n");  } return 0;}