HDU 1878 欧拉回路
欧拉回路
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
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
解题思路:
本题有多组测试数据,每组给出顶点数n与边数m,之后m行给出每条边的信息,想要求出欧拉回路是否存在,学过离散数学的同志应该明白,只要无向连通图中每个点的度都为偶数,该图一定存在欧拉回路。
那么问题就转化为了判断该图是否连通与判断所有顶点的度是否都为偶数。
判断是否连通可以使用并查集判断所有顶点是否都再一个集合中,顶点的度用一个数组来记录,由于是无向图所以再输入时顶点每出现一次该顶点的度便加一。
AC代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1010; 4 int f[maxn]; 5 int node[maxn]; 6 int getFather(int x) //并查集找爹函数 7 { 8 if(f[x] == x) 9 return x; 10 else 11 return f[x] = getFather(f[x]); 12 } 13 int main() 14 { 15 int n, m; 16 while(scanf("%d", &n) != EOF && n != 0){ 17 scanf("%d", &m); //输入顶点数与边数 18 int a, b; //a,b记录边两边连接的点 19 for(int i = 0; i <= n; i++){ 20 f[i] = i; 21 }//初始化所有顶点的父亲为自己,即所有顶点不连通 22 memset(node, 0, sizeof(node)); 23 //初始化所有点度为0 24 for(int i = 0; i < m; i++){ 25 scanf("%d%d", &a, &b); //输入便连接的两个点 26 node[a]++; //连接的两个点度都加一 27 node[b]++; 28 int fa, fb; 29 //获取a与b的父亲 30 fa = f[a]; 31 fb = f[b]; 32 //如果a与b不连通将它们标记为连通 33 if(fa != fb){ 34 f[b] = a; 35 } 36 } 37 int fx = f[1]; 38 bool flag = true; 39 //判断所有点是否再一个集合中 40 for(int i = 2; i <= n; i++){ 41 if(fx != f[i]){ 42 flag = false; 43 break; 44 } 45 } 46 if(flag){ //如果图连通 47 for(int i = 1; i <= n; i++){ //判断所有点的度是否都为偶数 48 if(node[i] % 2 != 0){ 49 printf("0\n"); 50 flag = false; 51 break; 52 } 53 } 54 if(flag){ 55 printf("1\n"); 56 } 57 }else{ 58 printf("0\n"); 59 } 60 } 61 return 0; 62 }