题目描述:
你是一座大庄园的管家。庄园有很多房间,编号为0、1、2、3,...。你的主人是一个心不在焉的人,经常沿着走廊随意地把房间的门打开。多年来,你掌握了一个诀窍:沿着一个通道,穿过这些大房间,并把房门关上。你的问题是能否找到一条路径经过所有开着门的房间,并使得:1) 通过门后立即把门关上;
2) 关上了的门不再打开;
3) 最后回到你自己的房间(房间0),并且所有的门都已经关闭了。
在本题中,给定房间列表,及连通房间的、开着的门,并给定一个起始房间,判断是否存在这样的一条路径。不需要输出这样的路径,只需判断是否存在。假定任意两个房间之间都是连通的(可能需要经过其他房间)。
输入描述:
输入文件包含多个(最多可达100 个)测试数据,每个测试数据之间没有空行隔开。
每个测试数据包括3 部分:
起始行-格式为“START M N”,其中M 为管理员起始所处的房间号,N 为房间的总数(1≤N≤20);
房间列表-一共N 行,每行列出了一个房间通向其他房间的房间号(只需列出比它的号码大的房间号,可能有多个,按升序排列),比如房间3 有门通向房间1、5、7,则房间3 的信息行内容为“5 7”,第一行代表房间0,最后一行代表行间N-1。有可能有些行为空行,当然最后一行肯定是空行,因为N-1 是最大的房间号;两个房间之间可能有多扇门连通。
终止行-内容为"END"。
输入文件最后一行是"ENDOFINPUT",表示输入结束。
输出描述:
每个测试数据对应一行输出,如果能找到一条路关闭所有的门,并且回到房间0,则输出"YESX",X 是他关闭的门的总数,否则输出"NO"。
- 分析:
- 1) 如果所有的房间都有偶数个门(通往其他房间),那么有欧拉回路,可以从0 号房间出发,回到0 号房间。但是这种情况下,出发的房间必须为0,因为要求回到0 号房间。
- 2) 有两个房间的门数为奇数,其余的都是偶数,如果出发的房间和0 号房间的门数都是奇数,那么也可以从出发的房间到达0 号房间,并且满足题目要求。但是不能从房间0 出发,必须从另一个门数为奇数的房间出发。
- 代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
string s,e;
int m,n;
int door[20];
int main(){
while(cin>>s){
int doors=0;
if(s=="ENDOFINPUT")
break;
cin>>m>>n;
int odd=0,even=0;
char str[1005];
getchar();
memset(door,0,sizeof door);
for(int i=0;i<n;i++){
gets(str);
int x;
int len=strlen(str);
for(int j=0;j<len;j++){
if(str[j]!=' '){
x=str[j]-'0';
doors++;
door[i]++;
door[x]++;
}
}
}
cin>>e;
for(int i=0;i<n;i++){
if(door[i]%2==1) odd++;
else even++;
}
if(odd==0&&m==0){
printf("YES %d\n",doors);
}else if(odd==2&&door[m]%2==1&&door[0]%2==1&&m!=0){
printf("YES %d\n",doors);
}else {
printf("NO\n");
}
}
return 0;
}