POJ 1300 Door Man【欧拉回路】

题目链接

题目描述:

你是一座大庄园的管家。庄园有很多房间,编号为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
",doors);
        }else if(odd==2&&door[m]%2==1&&door[0]%2==1&&m!=0){
            printf("YES %d
",doors);
        }else {
            printf("NO
");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/kzbin/p/9205208.html