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
这道题是欧拉回路的基础题,需要用到两部分:并查集 + 欧拉回路判定定理 。 并查集判断图是否连通 ,欧拉回路判定定理:在一个连通图G中存在欧拉回路的充要条件是图G中不存在奇度顶点。
请看代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<cstdlib> #include<queue> using namespace std ; const int MAXN = 1005 ; int set[MAXN] ; int d[MAXN] ; // 存顶点的度 inline void RD (int &a) // 输入优化 { a = 0 ; char t ; while ((t = getchar()) && t >= '0' && t <= '9') { a = a * 10 + t - '0' ; } } int find(int x) // 并查集 { int r = x ; while ( r != set[r] ) { r = set[r] ; } return r ; } int main() { int n , m ; while (1) { RD(n) ; if(n == 0) break ; memset(set , 0 , sizeof(set)) ; memset(d , 0 , sizeof(d)) ; RD(m) ; int i ; for(i = 1 ; i <= n ; i ++) // 初始化并查集 { set[i] = i ; } for(i = 0 ; i < m ; i ++) { int a , b ; RD(a) ; RD(b) ; d[a] ++ ; d[b] ++ ; int ta , tb ; ta = find(a) ; tb = find(b) ; if(ta < tb) { set[tb] = ta ; } else set[ta] = tb ; } int sumj = 0 ; int fz = 0 ; for(i = 1 ; i <= n ; i ++) { if(set[i] == i) { fz ++ ; } if(d[i] % 2 == 1) { sumj ++ ; } } if(fz > 1 || sumj > 0) { printf("0 ") ; } else { printf("1 ") ; } } return 0 ; }