C++ [图论算法详解] 欧拉路欧拉回路

news2025/1/19 2:39:37

蒟蒻还在上课,所以文章更新的实在慢了点

那今天就来写一篇这周刚学的欧拉路和欧拉回路吧

讲故事环节: 

一个风雪交加的夜晚

18世纪初普鲁士的哥尼斯堡,有一条河穿过,河上有两个小岛,有七座桥把两个岛与河岸联系起来。有个人提出一个问题:一个步行者怎样才能不重复、不遗漏地一次走完七座桥,最后回到出发点。后来大数学家欧拉把它转化成一个几何问题——一笔画问题。

大概就是这么个图

就是现在人们所说的一笔画问题

回归题目

上面这个图太乱了,根本无法分析

嗯~熟悉多了

难受多了 

现在的问题就是,如果不重复且不遗漏地走过所有的边(点可以无限次走,没有限制)

当然不指望你把它证明出来(bushi)

我们的大数学家欧拉,找到了它的充要条件

1.奇点的数目不是0个就是2个

奇点:就是度为奇数(如果是有向图就是入读+出度=奇数),反之为偶点

概念:

无向图:

欧拉路:对于一个图,每条边可以且只能访问一次

欧拉回路:在欧拉图的情况下,最后要回到原点。也就是说欧拉路不一定是欧拉回路,但欧拉回路一定是欧拉路

欧拉路有且只有0或2个奇点,欧拉回路不能有奇点。如果一个连通图有2n个奇点,那么这个图最少要k笔完成

有向图:

欧拉路:至多一个顶点入度和出度相差为1,其他顶点入度和出度全部相同

欧拉回路:每个顶点入度和出度都一样

举个栗子:

假设一个图是一个“田”

每个拐角处都是一个点

按照上面说的,一个图有2n个奇点,这个图最少要k笔完成

 

这个图一共四个奇点,所以至少需要2笔完成

 解决方法:

1.dfs

第一步:判断图是否连通(不联通就啥也别说了)

第二步:判断奇点个数

很简单,但是使用dfs的话,就需要很多数组,并且用邻接矩阵是最方便的,所以费空间

2.并查集

分为G1和G2两个集合,G1表示已经联通的,G2表示未联通的

利用父亲表示法合并集合效率最高,也是上面那两步

代码:

并查集

#include<iostream>
using namespace std;

#define N 21

int e[N][N];
int du[N];
int total;
int path[405];
int pos;
int vis[N];
int n,m;

int father[N];
int h[N];

void make()
{
    for(int i=1;i<=n;i++)
    {
        h[i]=1;
        father[i]=i; 
    }   
}

int find(int a)
{
    if(father[a]!=a)
    {
        return father[a]=find(father[a]);
    }
    else
        return father[a];
}

void join(int a,int b)
{
   a=find(a);
   b=find(b);
   if(a==b) return;
   if(h[a]>=h[b]) 
   {
       father[b]=a;
       h[a]+=h[b];
       h[b]=0;
   }
   else if(h[a]<h[b])
   {
       father[a]=b;
       h[b]+=h[a];
       h[a]=0;
   }
}

void findpath(int s)
{
	for(int j=1;j<=n;j++)
	{
		if(e[s][j]==1)
		{
			e[s][j]=e[j][s]=0x7f;
			findpath(j);
		}
	}
	path[++pos]=s;
}

int main(){
	int a,b;
	cin>>n>>m;
	memset(e,0x7f,sizeof(e));
	make();


	for(int i=1;i<=m;i++)
	{
        cin>>a>>b;
		e[a][b]=e[b][a]=1;
        du[a]++;
		du[b]++;

		join(a,b);
	}

    int f=find(1);
	for(int i=2;i<=n;i++)
	{
        if(find(i)!=f)
		{
			cout<<"NO";
		    return 0;
		}
	}


	// if(h[f]!=n)
	// {
	// 	cout<<"NO";
	// 	return 0;
	// }

    total=0;
	int st=1;
	for(int i=1;i<=n;i++)
	{
		if(du[i]%2) 
		{
			total++;
			st=i;
		}
	}

	if(total!=0 && total!=2)
	{
		cout<<"NO";
		return 0;
	}

	findpath(st);


	for(int i=1;i<=pos;i++)
	{
		printf("%d ",path[i]);
	}
	
	return 0;
}

dfs深搜:


#include<iostream>
using namespace std;
#define N 21
int e[N][N];
int du[N];
int total;
int path[405];
int pos;
int vis[N];
int n,m;

void dfs(int i)
{
    vis[i]=true;
	total++;
	for(int j=1;j<=n;j++)
	{
		if(e[i][j]==1 && !vis[j]) 
		    dfs(j);
	}
}

void findpath(int s)
{
	for(int j=1;j<=n;j++)
	{
		if(e[s][j]==1)
		{
			e[s][j]=e[j][s]=0x7f;
			findpath(j);
		}
	}
	path[++pos]=s;
}

int main(){
	int a,b;
	cin>>n>>m;
	memset(e,0x7f,sizeof(e));
	for(int i=1;i<=m;i++)
	{
        cin>>a>>b;
		e[a][b]=e[b][a]=1;
        du[a]++;
		du[b]++;
	}

	dfs(1);
	if(total!=n)
	{
		cout<<"NO";
		return 0;
	}

    total=0;
	int st=1;
	for(int i=1;i<=n;i++)
	{
		if(du[i]&1) 
		{
			total++;
			st=i;
		}
	}
    
	if(total!=0 && total!=2) 
	{
		cout<<"NO";
		return 0;
	}

	findpath(st);

	for(int i=1;i<=pos;i++)
	{
		printf("%d ",path[i]);
	}

	return 0;
}

例题:

题目描述

如果一个无向图存在一笔画,则一笔画的路径叫做欧拉路,如果最后又回到起点,那这个路径叫做欧拉回路。

输入

第一行n,m,0 < n <=20,表示有n个点,m条边,以下m行描述每条边连接的两点。

输出

如果有欧拉路或欧拉回路,输出一条路径即可,顶点之间由空格隔开。

如果没有,输出NO
 

样例输入1

5 5
1 2
2 3
3 4
4 5
5 1

样例输出1

1 5 4 3 2 1

 


 

这题直接套模板就没问题

分析优劣点:

 1.dfs

简单,实用

费空间费时间

2.并查集

效率高,快速,不费时间不费空间

难,费劲

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

万字长文:C语言实践小练习汇总指南!

万字长文&#xff1a;C语言实践小练习汇总指南!0.说在前面1.i与i总结1.1 i与i1.2 区别总结&#xff1a;2.大小写转化3.交换字符串3.1 使用传字符串地址3.2 使用strcpy函数3.3 自写字符串交换函数3.4 同3.3自写函数4.字符串中单词4.1 统计字符串中单词个数4.2 最长单词及位置5.字…

注册页面小案例

运行截图&#xff1a; 知识点&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge"> <meta name&…

SwinTrack: A Simple and Strong Baseline for Transformer Tracking(NIPS2022)

SwinTrack摘要介绍相关工作方法实验摘要 近期&#xff0c;Transformer在视觉跟踪方面进行了深入探索&#xff0c;并展示了显著的潜力。然而&#xff0c;现有的基于Transformer的跟踪器主要将Transformer用于融合和增强由卷积神经网络提取的特征&#xff0c;Transformer在表征学…

另一种迁移xxl-job任务的方法,适合不满足数据迁移条件

以为多个项目组同时使用一个xxl-job&#xff0c;同时涉及到版本提升&#xff0c;由此不太满足数据库数据迁移&#xff0c;所以这里提供另一种解决办法 使用工具&#xff1a;postman,json转excel&#xff0c;excel 核心&#xff1a;excel拼接&#xff1a; 1.使用f12抓取xxl任务访…

什么是 SMART 并如何使用这个方法取得新的成就

SMART原则也许大家并不陌生&#xff0c;很多企业常常采用以激励员工更加高效的工作&#xff0c;或是被一些企业广泛采用&#xff0c;制定并实施绩效考核方案&#xff0c;SMART原则属于目标管理的范畴&#xff0c;最早是管理大师彼得德鲁克在著作中提出的。 ONLYOFFICE ONLYOFFI…

Nginx快速上手

Nginx快速上手 OVERVIEWNginx快速上手一、基本概念1.Nginx初步认识2.正向/反向代理&#xff08;1&#xff09;正向代理&#xff08;2&#xff09;反向代理二、Nginx 安装和配置1.安装2.Nginx指令3.Nginx配置三、Nginx的使用1.Web服务器&#xff08;1&#xff09;静态网页存储目…

Java对日开发成趋势?网友:找工作打开了新思路

近两年行业环境起起伏伏&#xff0c;企业降本增效&#xff0c;提高人才招聘的门槛&#xff0c;导致大家找工作时觉得越来越难&#xff0c;尤其是Java开发&#xff0c;主打的就是一个“卷”&#xff01; 不过行业变革&#xff0c;挑战与机遇并存。Java作为编程语言排行榜的常年第…

Java8 判空新写法(Optional方式)

1 引言 在文章的开头&#xff0c;先说下NPE问题&#xff0c;NPE问题就是&#xff0c;我们在开发中经常碰到的NullPointerException.假设我们有两个类&#xff0c;他们的UML类图如下图所示 在这种情况下&#xff0c;有如下代码 user.getAddress().getProvince();这种写法&…

计算机网络 实验四

⭐计网实验专栏&#xff0c;欢迎订阅与关注&#xff01; ★观前提示&#xff1a;本篇内容为计算机网络实验。内容可能会不符合每个人实验的要求&#xff0c;因此以下内容建议仅做思路参考。 一、实验目的 理解ARP协议的工作原理掌握ARP、ICMP 处理过程 二、实验内容 利用网络…

BearPi环境搭建及基本使用

这是一篇总结&#xff0c;一些坑的记录 具体教程请访问&#xff1a; BearPi-HM_Nano: 小熊派BearPi-HM Nano开发板基于HarmonyOS的源码 - Gitee.com 第一步&#xff1a;安装虚拟机 不做赘述 第二步&#xff1a;下载资源 这里要用到ubuntu的一些基础知识&#xff0c;不会的…

HTTP Flood攻击与防御原理

一.引言HTTP Flood攻击DDoS的一种,别称叫做CC攻击(CC是Challenge Collapsar的缩写&#xff0c;而Collapsar是国内一家著名安全公司的DDoS防御设备)&#xff0c;是针对Web服务在第七层协议发起的攻击&#xff0c;重点在于突破前端的cache,通过HTTP头中的字段设置直接到达Web Ser…

精通线程池,看这一篇就够了

一&#xff1a;什么是线程池 当我们运用多线程技术处理任务时&#xff0c;需要不断通过new的方式创建线程,这样频繁创建和销毁线程&#xff0c;会造成cpu消耗过多。那么有没有什么办法避免频繁创建线程呢&#xff1f; 当然有&#xff0c;和我们以前学习过多连接池技术类似&…

安全头响应头(一)Content-Security-Policy

一 Content Security Policy CSP 中文翻译 ① 背景引入 "重点提炼" 1) CSP最初被设计用来减少XSS跨站点脚本攻击,该规范后续版本还可防止其他如点击劫持形式的攻击2) CSP 的实质就是白名单制度[1]、网站开发者明确告诉客户端,哪些外部资源可以加载和执行,等同…

STM32H750ZBT6核心板设计

成品图 注意事项 1、主频无法设置480Mhz,只能最高设置为400Mhz 设置版本号为V版本&#xff0c;即稳定版本即可以设置主频为480Mhz了&#xff0c;不清楚自己的STM32H750是什么版本&#xff0c;可以查看芯片上丝印&#xff0c;ST公司LOGO旁边有个Y/V&#xff0c;即是版本号。 2…

零碎Java

1. 1995年Sun公司开发了java 2009年Oracle收购了Sun公司 其中2004年的java5.0和2014年的java8.0更新力度最大 java特性&#xff1a;第一至今已有20多年了 第二编程语言 第三应用广泛 2. 二进制中逢二进一 11 10 111100 0000万 0000&#xff0c;0000亿 …

RK3568平台开发系列讲解(设备驱动篇)V4L2程序实现流程

🚀返回专栏总目录 文章目录 一、V4L2 进行视频采集二、命令标识符三、V4L2程序实例3.1、打开设备3.2、查询设备属性3.3、显示所有支持的格式3.4、设置图像帧格式3.5、申请缓冲区3.6、将申请的缓冲帧从内核空间映射到用户空间3.7、将申请的缓冲帧放入队列,并启动数据流3.8、启…

配置mpls vpn MCE组网

实验三&#xff1a;配置mpls vpn MCE组网 1、实验环境&#xff1a; 某公司需要通过mpls vpn实现总部和分部的互访&#xff0c;并且要实现不同部门之间的业务隔离&#xff0c;为了节省开支&#xff0c;总公司使用MCE设备接入不同的部门。要求分公司A只能访问总公司的部门A&…

分子生物学 第二章 遗传物质

文章目录第二章 遗传物质第一节 遗传物质的分子本质大多数生物体的遗传物质是DNA有些生物体的遗传物质是RNA蛋白质能否充当遗传物质第二节 核酸的结构1 DNA双螺旋结构的特征2 影响DNA双螺旋结构稳定性的因素3 DNA结构的多态性4 DNA多链结构5 DNA的超螺旋结构6 RNA的二级结构第三…

性能测评:腾讯云轻量2核4G5M服务器CPU内存带宽流量系统盘

2核4G云服务器可以选择腾讯云轻量应用服务器&#xff0c;自带5M公网带宽&#xff0c;5M带宽下载速度峰值可达640KB/秒&#xff0c;系统盘为60GB SSD盘&#xff0c;每月500GB流量包&#xff0c;折合每天16GB流量&#xff0c;2核4G5M轻量服务器一年168、198元15个月、三年628元&a…

OpenMV快速上手 | OpenMV硬件版本概述及HelloWorld

文章目录一、OpenMV1. 什么是OpenMV2. OpenMV版本2.1. OpenMV1&#xff08;M4 V1&#xff09;2.2. OpemMV2&#xff08;M4 V2&#xff09;2.3. OpenMV3&#xff08;M7&#xff09;2.4. OpenMV4&#xff08;H7&#xff09;二、OpenMV开发环境搭建三、hello world1. 连接OpenMV2.…