现在的位置: 首页 > 综合 > 正文

欧拉回路

2014年02月25日 ⁄ 综合 ⁄ 共 1136字 ⁄ 字号 评论关闭

前言

睡觉前禁止自己的胡思乱想,上九度上ac了一道并查集的题目

题目

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

思路

  1. 首先,判断是否构成连通图,用并查集实现
  2. 判断每个节点的度数是否为偶数(0除外)

ac代码

#include <stdio.h>
#include <stdlib.h>

int father[1001];
int degree[1001];

void init_process(int n)
{
	int i;

	for (i = 0; i < n; i ++) {
		father[i] = i;
		degree[i] = 0;
	}
}

int find_set(int x)
{
	while (father[x] != x)
		x = father[x];

	return x;
}

void union_set(int x, int y)
{
	x = find_set(x);
	y = find_set(y);

	if (x != y)
		father[x] = y;
}


int main()
{
	int n, m, u, v, i, count1, count2;

	while (scanf("%d", &n) != EOF && n) {
		init_process(n);
		
		scanf("%d", &m);
		while(m --) {
			scanf("%d %d", &u, &v);
			degree[u - 1] ++;
			degree[v - 1] ++;
			union_set(u - 1, v - 1);
		}

		for (i = count1 = count2 = 0; i < n; i ++) {
			if (father[i] == i) {
				count1 ++;
			}
			if (degree[i] == 0 || degree[i] % 2 == 1) {
				count2 ++;
			}
		}

		if (count1 == 1 && count2 == 0) {
			printf("1\n");
		}else {
			printf("0\n");
		}
	}

	return 0;
}
/**************************************************************
	Problem: 1027
	User: wangzhengyi
	Language: C
	Result: Accepted
	Time:120 ms
	Memory:920 kb
****************************************************************/

抱歉!评论已关闭.