poj1300 Door Man(欧拉回路)


Door Man

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 2449   Accepted: 983

Description

You are a butler in a large mansion. This mansion has so many rooms that they are merely referred to by number (room 0, 1, 2, 3, etc...). Your master is a particularly absent-minded lout and continually leaves doors open throughout a particular floor of the
house. Over the years, you have mastered the art of traveling in a single path through the sloppy rooms and closing the doors behind you. Your biggest problem is determining whether it is possible to find a path through the sloppy rooms where you:

  1. Always shut open doors behind you immediately after passing through
  2. Never open a closed door
  3. End up in your chambers (room 0) with all doors closed

In this problem, you are given a list of rooms and open doors between them (along with a starting room). It is not needed to determine a route, only if one is possible.

Input

Input to this problem will consist of a (non-empty) series of up to 100 data sets. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets.

A single data set has 3 components:

  1. Start line - A single line, "START M N", where M indicates the butler‘s starting room, and N indicates the number of rooms in the house (1 <= N <= 20).
  2. Room list - A series of N lines. Each line lists, for a single room, every open door that leads to a room of higher number. For example, if room 3 had open doors to rooms 1, 5, and 7, the line for room 3 would read "5 7". The first line in the list represents
    room 0. The second line represents room 1, and so on until the last line, which represents room (N - 1). It is possible for lines to be empty (in particular, the last line will always be empty since it is the highest numbered room). On each line, the adjacent
    rooms are always listed in ascending order. It is possible for rooms to be connected by multiple doors!
  3. End line - A single line, "END"

Following the final data set will be a single line, "ENDOFINPUT".

Note that there will be no more than 100 doors in any single data set.

Output

For each data set, there will be exactly one line of output. If it is possible for the butler (by following the rules in the introduction) to walk into his chambers and close the final open door behind him, print a line "YES X", where X is the number of doors
he closed. Otherwise, print "NO".

Sample Input

START 1 2
1

END
START 0 5
1 2 2 3 3 4 4

END
START 0 10
1 9
2
3
4
5
6
7
8
9

END
ENDOFINPUT

Sample Output

YES 1
NO
YES 10

Source

South Central USA 2002

很经典的欧拉回路问题,在图论算法书上看到的。。。

1.如果所有的房间都有偶数个门,那么就有欧拉回路。但是这种情况下必须从0出发才能够回到0;

2.如果有只有两个门是奇数,那么这两个门一定有一个是0,而且不从0出发。

3.其它情况都不行。

附上代码:

#include <stdio.h>
#include <string.h>
int main()
{
	char str[128];
	int door[25],m,n;
	while(gets(str))//gets可以接收空格
	{
		if(str[0]=='S')
		{
			sscanf(str,"%*s %d %d",&m,&n);//对于sscanf不懂的可以百度。这里*s是忽略str的第一个字符串(空格)
			for(int i=0;i<n;i++)
			door[i]=0;//计算每个房间有几道门
			int doors=0;//计算共有多少门
			for(int i=0;i<n;i++)
			{
				gets(str);
				int k=0,j;
				while(sscanf(str+k,"%d",&j)==1)//读取门
				{
					doors++;
					door[i]++;
					door[j]++;
					if(str[k]&&str[k]==' ') k++;//有空格+1就不说了吧
					while(str[k]&&str[k]!=' ') k++;//举个例子,如果房间号是12,就要+2了0.0
				}

			}
			gets(str);
			int odd=0,even=0;
			for(int i=0;i<n;i++)
			{
				if(door[i]%2)
				odd++;
				else
				even++;
			}
			if(odd==0&&m==0)
			printf("YES %d\n",doors);
			else if(odd==2&&door[m]%2&&door[0]%2&&m!=0)
			printf("YES %d\n",doors);
			else
			printf("NO\n",doors);
		}
		else
		break;
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 15:28:08

poj1300 Door Man(欧拉回路)的相关文章

POJ1300 Door Man 欧拉回路的判断

题目链接: 1300 题意: 一个房子中有(编号0~N-1)N个房间和X个连通两个房间的门,所有房间都是连通的,每次经过一扇门时这扇门会被关闭.问:一个人从M号房间出发能否成功到达0号房间并关闭所有门. 题解: 此题是欧拉回路的入门题,首先学习无向图欧拉回路的判断定理: 无向图G 存在欧拉通路的充要条件是:G 为连通图,并且G 仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点. 该题是固定起点和终点的的无向图. 所以能构成欧拉回路只有两种情况: 1 所有点的度数为偶数 2 起点终点度数为奇数

poj1300判断欧拉回路

对于连通图 无向图:1.无奇点,可以从任意一点出发回到原点. 2.存在奇点,且只有两个,从一奇点出发,另一奇点终止. 有向图:1.所有点入度等于出度. 2.只有两个点入度不等于出度,且其中一个点入度比出度大一另一个点的出度比入度大一. #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <

POJ1300(欧拉回路)

Door Man Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2139   Accepted: 858 Description You are a butler in a large mansion. This mansion has so many rooms that they are merely referred to by number (room 0, 1, 2, 3, etc...). Your mast

混合图的欧拉回路判定

对于有向图和无向图的欧拉回路判定,很容易做到.那对于混合图呢?? 混合图就是图中既存在无向边又存在有向边的图. 至于解法: 转载自这里 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路.因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路. 好了,现在每个点入度和出度之差均为偶数.那么将这个偶数除以2,得x.也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入.如果

hdu1116 欧拉回路

1 //Accepted 248 KB 125 ms 2 //欧拉回路 3 //以26个字母为定点,一个单词为从首字母到末尾字母的一条边 4 //下面就是有向图判断欧拉回路 5 //连通+节点入度和==出度和 或者 存在一对节点一个入度比出度大1,一个小1 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <queue> 10 using namespace s

POJ 1041 John&#39;s trip 无向图的【欧拉回路】路径输出

欧拉回路第一题TVT 本题的一个小技巧在于: [建立一个存放点与边关系的邻接矩阵] 1.先判断是否存在欧拉路径 无向图: 欧拉回路:连通 + 所有定点的度为偶数 欧拉路径:连通 + 除源点和终点外都为偶数 有向图: 欧拉回路:连通 + 所有点的入度 == 出度 欧拉路径:连通 + 源点 出度-入度=1 && 终点 入度 - 出度 = 1 && 其余点 入度 == 出度: 2.求欧拉路径 : step 1:选取起点(如果是点的度数全为偶数任意点为S如果有两个点的度数位奇数取一

寒假集训日志(二)——最小生成树,拓扑排序,欧拉回路,连通路

今天学的内容挺多的. (一)首先说最小生成树,两种算法: 1.Kruskal算法( 将边排序,然后再选,关键在于检查是否连通,使用并查集) 2.Prim算法(使用点集,有点类似与最短路的算法) 第一题是并查集算法的使用: A - The Suspects Time Limit:1000MS     Memory Limit:20000KB     64bit IO Format:%I64d & %I64u Submit Status Description 严重急性呼吸系统综合症( SARS),

HDU-1878 判断无向图欧拉回路,水

HDU 1878 题意:问一个无向图是否存在欧拉回路. 总结: 1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图.2.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图.3.要判断一个混合图G(V,E)(既有有向边又有无向边)是欧拉图,方法如下:假设有一张图有向图G',在不论方向的情况下它与G同构.并且G'包含了G的所有有向边.那么如果存在一个图G'使得G'存在欧拉回路,那么G就存在欧拉回路. // HDU-1878 #include<bits/stdc++

HDU 5883 F - The Best Path 欧拉通路 &amp; 欧拉回路

给定一个图,要求选一个点作为起点,然后经过每条边一次,然后把访问过的点异或起来(访问一次就异或一次),然后求最大值. 首先为什么会有最大值这样的分类?就是因为你开始点选择不同,欧拉回路的结果不同,因为是回路,所以你的开始点就会被访问多一次,所以如果是欧拉回路的话,还需要O(n)扫一次,枚举每个点作为起点. 欧拉通路的话,结果是固定的,因为只能从奇数度小的那个点作为起点,奇数度大的那个点作为终点. 关于点的访问次数:anstime  = Degree[i] / 2; //如果是奇数的,还要加上一.