hdu 1878 欧拉回路(联通<并查集> + 偶数点)

欧拉回路
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18576    Accepted Submission(s): 7219

Problem Description
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
 
Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
束。
 
Output
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
 
Sample Input
3 3
1 2
1 3
2 3
3 2
1 2
2 3
0
 
Sample Output
1
0

C/C++:

 1 #include <map>
 2 #include <queue>
 3 #include <cmath>
 4 #include <vector>
 5 #include <string>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <climits>
 9 #include <iostream>
10 #include <algorithm>
11 #define INF 0x3f3f3f3f
12 using namespace std;
13 const int my_max = 1010;
14 
15 int n, m, my_pre[my_max], a, b, my_node[my_max];
16 
17 int my_find(int x)
18 {
19     int n = x;
20     while (n != my_pre[n])
21         n = my_pre[n];
22     int i = x, j;
23     while (n != my_pre[i])
24     {
25         j = my_pre[i];
26         my_pre[i] = n;
27         i = j;
28     }
29     return n;
30 }
31 
32 bool is_eulerian()
33 {
34     for (int i = 1; i <= n; ++ i)
35         if (my_node[i] & 1) return false;
36     int temp = my_find(1);
37     for (int i = 2; i <= n; ++ i)
38         if (my_find(i) != temp) return false;
39     return true;
40 }
41 
42 int main()
43 {
44     while (scanf("%d", &n), n)
45     {
46         scanf("%d", &m);
47         memset(my_node, 0, sizeof(my_node));
48         for (int i = 1; i <= n; ++ i)
49             my_pre[i] = i;
50 
51         while (m --)
52         {
53             scanf("%d%d", &a, &b);
54             my_node[a] ++, my_node[b] ++;
55             int n1 = my_find(a), n2 = my_find(b);
56             my_pre[n1] = n2;
57         }
58 
59         if (is_eulerian()) printf("1
");
60         else printf("0
");
61     }
62     return 0;
63 }
原文地址:https://www.cnblogs.com/GetcharZp/p/9497895.html