浙江大学机试--欧拉回路

题目: 牛客网链接

概述: 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?

思路: 确定无向图欧拉回路的充要条件:除孤立节点外,其它节点满足 1.连通 2.度为偶数。这里采用并查集进行操作,具体思路写在注释里。

采用scanf可以提高输入效率,大幅度提高。很多学校的oj要求的是连续输入很多组数据,之前因为忘记使用EOF导致运行超时,所以这一点一定要记住。
另外并查集自己简单总结一下几个步骤,方便以后做连通图相关的问题。

  • 初步设置father数组:先给每个节点的father数组的相对应位置设置初始值。例如father[x] = x。这样做是为了防止孤立节点的问题。
  • 再设置father数组:这次根据给出的路径,把相连的点union起来
  • 看是不是都连在一起(除了孤立节点):就找一个度大于1的作为起始点,找他的father,然后后面找所有的非孤立节点的father应该都是一样的。

#include <iostream>
#include <memory.h>
using namespace std;

int father[1005], cnt[1005];

int find(int x) {
    while (x != father[x])
    {x = father[x];}
    return x;
}

void union_find(int x, int y)
{
	 x = find(x);
	 y = find(y);
	 if(x != y) father[x] = y; 
}



int main()
{
	int  N, M; //N对应着N个节点,M对应着M条边 
	
	while(scanf("%d", &N) != EOF && N)
	{
		scanf("%d", &M);
		fill(father, father + 1005, 0);
		
		//先把每个点的父节点设置成自己,保障孤立节点 
		for(int i = 1; i <= N; i++) father[i] = i;
		//输入联通的两个节点
		for(int i = 1; i <= M; i++)
		{
			int x, y;
			scanf("%d", &x);
			scanf("%d", &y);
			cnt[x]++;
			cnt[y]++;
			union_find(x, y);
		}
		
		//判断是否所有点的度都为偶数,如果存在不是偶数的,那么报错 
		bool flag = true;
		for(int i = 1; i <= N; i++)
		{
			if(cnt[i] % 2 != 0)
			{
				flag = false;
			}
		}
		if(!flag)  
		{
		printf("%d\n", flag);
	    continue;
		}
		
		//查看所有点是否联通
		//先找一个非孤立节点
		int t;
		for(int i = 1; i <= N; i++)
		{
			if(cnt[i] != 0)
			{
				t = i;
				break;
			}
		} 
		//所有非孤立节点的父节点应该都是一个
		int fa = find(t);
		for(int i = 1; i <= N; i++) 
		{
			if(find(i) != fa && cnt[i] != 0)
			{
				flag = false;
				break;
			}
		}
		
		printf("%d\n", flag);
		
			 
	}
	
	return 0;
} 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值