看到这道题我激动了,我靠,不得不发自内心的说一句,华为的选题还是挺好的,这道题很有趣,需要两步判断
1.判断整幅图是不是联通的
2.判断这个这个连通图是否是欧拉回路
对于第一个问题,并查集就是为解决它而生的,我靠容我再次激动一下,我心心念念的并查集终于有用武之地了。下面给出我看了五遍以上的一个大神的博客
http://blog.csdn.net/dellaserss/article/details/7724401/
如果一遍看不懂,请多看几遍
对于第二个问题,就是需要判断所有点,度数为奇数的点的个数,只能是0个或者是2个
直接上代码了
#include<iostream>
#define Len 500
using namespace std;
int pre[Len];
void Init()
{
for (int i = 0; i<Len; i++)
{
pre[i] = i;
}
}
int Find(int n)
{
int r = n;
while (pre[r] != r)
{
r = pre[r] ;
}
//压缩路径
int j = n;
int k;
while (pre[j] != r)
{
k = pre[j];
pre[j] = r;
j = k;
}
return r;
}
void Union(int x, int y)
{
int rx = Find(x);
int ry = Find(y);
if (rx != ry)
{
pre[ry] = rx;
}
}
int main()
{
int num, count, oddPoint, max;
int x, y, i;
int edge[Len];
while (cin >> num)
{
Init();
count = 0;
oddPoint = 0;
max = 0;
memset(edge, 0, sizeof(int)*Len);
for (i = 0; i < num; i++)
{
cin >> x >> y;
Union(x, y);
edge[x]++;
edge[y]++;
if (x>max)
{
max = x;
}
if (y>max)
{
max = y;
}
}
for (i = 1; i <= max; i++)
{
if (edge[i] > 0)
{
if (pre[i] == i)
{
count++;
}
if (edge[i] % 2 == 1)
{
oddPoint++;
}
}
}
if (count == 1 && (oddPoint == 0 || oddPoint == 2))
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
return 0;
}