题目大意:给出连通的房间,让你求能否从0走到M并且关闭了所有的房间,注意关闭的房间不能再次打开。题目已经告诉你图已经连通。
算法思路:就是让你求这个图是否是一个欧拉回路或者是欧拉图,当m==0的时候求是否是欧拉回路,当m!=0的时候求是否是欧拉图。
无向图欧拉回路的判定:图连通并且所有点的度是偶数。
无向图欧拉通路的判定:图连通并且度为奇数的点位0个或2个,且这两个奇点必为起点或终点。
有向图欧拉回路的判定:图连通且任意一点的入度等于出度。
有向图欧拉通路的判定:图连通且恰好只有2个点,其中一个出度比入度多一(起点),另一个入度比出度多一(终点)。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char str[30];
char str2[300];
int n,m,cnt;
int degree[200];
bool isEulerH()
{
for(int i=0;i<n;i++)
{
if(degree[i]%2!=0)
return false;
}
return true;
}
bool isEulerT(int st,int ed)
{
int k1=-1,k2=-1,sum=0;
for(int i=0;i<n;i++)
{
if(degree[i]%2!=0)
sum++;
if(degree[i]%2!=0&&k1==-1)
{
k1=i;
}
else if(degree[i]%2!=0&&k2==-1)
{
k2=i;
}
}
if(sum==1||sum>2)
return false;
else if((k2==st&&k1==ed)||(k2==ed&&k1==st))
return true;
return false;
}
int main()
{
while(true)
{
scanf("%s",str);
if(!strcmp(str,"START"))
{
cnt=0;
memset(degree,0,sizeof(degree));
scanf("%d%d",&m,&n);
getchar();
for(int i=0;i<n;i++)
{
// getchar();
gets(str2);
for(int j=0;j<strlen(str2);j++)
{
if(str2[j]!=' ')
{
degree[i]++;
degree[str2[j]-'0']++;
cnt++;
}
}
}
}
else if(!strcmp(str,"END"))
{
if(isEulerH()&&m==0)//若m==0说明原图需要是一个欧拉回路
{
printf("YES %d\n",cnt);
}
else if(isEulerT(0,m))//若m!=0则说明原图只需要是一个欧拉通路即可
{
printf("YES %d\n",cnt);
}
else
{
printf("NO\n");
}
}
else if(!strcmp(str,"ENDOFINPUT"))
{
break;
}
}
return 0;
}