题目解析:此题是欧拉回路,欧拉回路满足的条件:无论是有向图还是无向图前提条件都是图要连通,如果是无向图需要有0个奇度顶点或者2个奇度顶点,如果是有向图,在前两个条件的基础之上还要附加上一个条件:一个奇度顶点入度比出度大1,另一个奇度顶点出度比入度大1。所以要解决这样的问题,首先要判断图的连通性,在图是连通的前提下,再判断奇度顶点的个数。在判断图的连通性时,可以采用并查集,也可以用深搜,此篇采用了并查集,深搜将在下篇讲解。
代码如下:
01.
#include<stdio.h>
02.
#include<string.h>
03.
int
father[1010];
04.
void
init(
int
n)
//初始化father数组,初始时每一个结点的根是自己
05.
{
06.
for
(
int
i=1;i<=n;i++)
07.
father[i]=i;
08.
}
09.
int
find(
int
x)
//寻根函数
10.
{
11.
if
(x == father[x])
12.
return
x;
13.
return
father[x] = find(father[x]);
14.
}
15.
int
main()
16.
{
17.
int
icase;
18.
int
ans[1010];
//ans数组用来保存每个结点的度
19.
scanf
(
"%d"
,&icase);
20.
while
(icase--)
21.
{
22.
int
m,n;
23.
scanf
(
"%d%d"
,&m,&n);
24.
init(m);
25.
memset
(ans,0,
sizeof
(ans));
26.
int
a,b;
27.
for
(
int
i=1;i<=n;i++)
28.
{
29.
scanf
(
"%d%d"
,&a,&b);
30.
ans[a]++;
31.
ans[b]++;
32.
if
(find(a)!=find(b))
33.
father[a]=find(b);
//如果两个节点不在一个集合中,就合并这两个结点
34.
}
35.
int
c1=0,c2=0;
36.
for
(
int
i=1;i<=m;i++)
37.
{
38.
if
(father[i]==i)
39.
c1++;
//统计集合的个数
40.
if
(ans[i]%2==1)
41.
c2++;
//统计奇度顶点的个数
42.
}
43.
if
((c2==0||c2==2)&&c1==1)
44.
printf
(
"Yes\n"
);
45.
else
46.
printf
(
"No\n"
);
47.
}
48.
return
0;
49.
}