奇特的图形
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
总提交:129 测试通过:50
总提交:129 测试通过:50
描述
记得上小学奥数时,JacmY最喜欢做的题就是给一个图形,从它某一个顶点出发描这个图形,若恰通过图中每条边一次,看最后能否又回到起点。当时JacmY只懂得拿着铅笔随便画画试试,如果成功了,就说这个图能画下来,而他判断不能画下来的标准就是费了半天功夫都画不出来,当然这么做是不对的,特别当图形变得复杂时,JacmY是试不过来的。看着可怜的JacmY,你能帮帮他吗?
输入
第一行一个整数T代表样例的组数。
以下T组数据中,每组第一行是N,K,(2 <= N <= 100)分别代表当前图形有N个顶点,K条边,接下来K行中,每行两个整数X, Y( 1 <= X, Y <= N)代表顶点X和顶点Y之间有一条边。
每组数据之间有一空行。
输出
如果当前图形能按照题目要求描出来,则输出“YES”(不包括引号),否则输出“NO”。
样例输入
3
3 3
1 2
2 3
1 3
3 2
1 2
2 3
2 2
1 2
1 2
样例输出
YES
NO
YES
题目来源
Internet
//一次通过——自己的想法:)全连通+每个节点的度(出度+入度)为偶数
//测试案例3代表节点1、2之间有2条边,所以才能回去
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
int a[100][100];
int tmp[100][100];
int n, k;
int num[100];
bool allArrive()
{
memset(tmp, 0, sizeof(tmp));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j] < INF)
tmp[i][j] = tmp[j][i] = 1;
}
tmp[i][i] = 1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(tmp[i][j])
{
for(int k=1;k<=n;k++)
{
if(tmp[k][i])
tmp[k][j] = tmp[j][k] = 1;
}
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(!tmp[i][j])
return false;
return true;
}
bool oushu()
{
for(int i=1;i<=n;i++)
if(num[i]%2 != 0)
return false;
return true;
}
int main()
{
int ncase;
scanf("%d",&ncase);
while(ncase--)
{
int x, y;
memset(a, INF, sizeof(a));
memset(num, 0, sizeof(num));
scanf("%d%d",&n,&k);
while(k--)
{
scanf("%d%d",&x,&y);
a[x][y] = a[y][x] = 1;
num[x]++;
num[y]++;
}
if(allArrive() == false || oushu() == false) printf("NO\n");
else printf("YES\n");
}
return 0;
}