欧拉回路欧拉路【详解】

1.引入

2.概念

3.解决方法

4.例题

5.回顾

1.引入

经典的七桥问题

哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示。

可否走过这样的七座桥,而且每桥只走过一次?

你怎样证明?

后来大数学家欧拉把它转化成一个几何问题——一笔画问题。

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

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

奇点:就是度为奇数(有向图是判断出度与入度是否相等),反之为偶点

有向图1、连通 2、所有点出度等于入度或者一个点入度-出度=1,另外一个点出度-入度=1

2.图是联通的

2.概念

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

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

3.解决方法:
1.dfs

第一步:判断图是否连通

第二步:判断奇点个数

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

2.并查集

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

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

4.例题

(1)

一笔画问题

题目描述

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

输入

第一行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.并查集

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

难,费劲

本蒟蒻用的是DFS

1、判断连通性,没有判断
就是要判断所有点都是连通的(dfs或者并查集)
如果不连通输出NO

2、如果连通,统计奇点的个数
如果奇点个数为0则为欧拉回路
如果奇点个数为2则为欧拉路
其他情况则输出NO

3、输出一个路径

dfs:

void dfs(int i)
{for(int j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++reckon]=i;return;
}

调题过程很坎坷

40分:(未判断NO)

#include<bits/stdc++.h>
using namespace std;
#define N 510
int g[N][N],d[N],c[N],n,m,p;
int dfs(int i)
{int j;for(j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++p]=i;return 0;
}int main()
{cin>>n>>m;int x,y;memset(g,0,sizeof(g));for(int i=1;i<=m;i++){cin>>x>>y;g[x][y]=1;g[y][x]=1;d[x]++;d[y]++;}int z=1;for(int i=1;i<=n;i++){if(d[i]%2==1){z=i;}}dfs(z);for(int i=1;i<=p;i++){cout<<c[i]<<" ";}return 0;
}//40分

60分:(未判断连通性)

#include<bits/stdc++.h>
using namespace std;
#define N 510
int g[N][N],d[N],c[N],n,m,reckon,oddity_point;
void dfs(int i)
{for(int j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++reckon]=i;return;
}int main()
{cin>>n>>m;int x,y;memset(g,0,sizeof(g));for(int i=1;i<=m;i++){cin>>x>>y;g[x][y]=1;g[y][x]=1;d[x]++;d[y]++;}int z=1;for(int i=1;i<=n;i++){if(d[i]%2==1){z=i;oddity_point++;}}dfs(z);if(oddity_point!=2&&oddity_point!=0){cout<<"NO";return 0;}for(int i=1;i<=reckon;i++){cout<<c[i]<<" ";}return 0;
}//60分

100分AC:

#include<bits/stdc++.h>
using namespace std;
#define N 510
int g[N][N],d[N],c[N],n,m,reckon,oddity_point,lt;
void dfs(int i)
{for(int j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++reckon]=i;return;
}int main()
{cin>>n>>m;int x,y;memset(g,0,sizeof(g));for(int i=1;i<=m;i++){cin>>x>>y;g[x][y]=1;g[y][x]=1;d[x]++;d[y]++;}int z=1;for(int i=1;i<=n;i++){if(d[i]%2==1){z=i;oddity_point++;}if(d[i]==0){lt++;}}dfs(z);if(oddity_point!=2&&oddity_point!=0){cout<<"NO";return 0;}if(lt!=0){cout<<"NO";return 0;}for(int i=1;i<=reckon;i++){cout<<c[i]<<" ";}return 0;
}//AC

5.回顾

因为我的测试点没有测出来问题所在:

问题:

如果1-2-3-4四个点一个环,5-6两个点连通,奇点个数为2,但整个图不连通

我的程序会说YES

可是根本不连通

输出5 6

碰上这样的就必须用DFS,并查集了

本蒟蒻偷了个小懒

因为碰上这样的(错误)输出一定不会是m+1个

所以判断一下输出个数是不是不等于m+1

如果不等于,输出NO。

#include<bits/stdc++.h>
using namespace std;
#define N 510
int g[N][N],d[N],c[N],n,m,reckon,oddity_point,lt;
void dfs(int i)
{for(int j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++reckon]=i;return;
}
int main()
{cin>>n>>m;int x,y;memset(g,0,sizeof(g));for(int i=1;i<=m;i++){cin>>x>>y;g[x][y]=1;g[y][x]=1;d[x]++;d[y]++;}int z=1;for(int i=1;i<=n;i++){if(d[i]%2==1){z=i;oddity_point++;}if(d[i]==0){lt++;}}dfs(z);if(oddity_point!=2&&oddity_point!=0){cout<<"NO";return 0;}if(lt!=0){cout<<"NO";return 0;}if(reckon!=m+1){cout<<"NO";return 0;}for(int i=1;i<=reckon;i++){cout<<c[i]<<" ";}return 0;
}

最终,我们把无用的代码段删掉,调试结束

#include<bits/stdc++.h>
using namespace std;
#define N 510
int g[N][N],d[N],c[N],n,m,reckon,oddity_point,lt;
void dfs(int i)
{for(int j=1;j<=n;j++){if(g[i][j]==1){g[i][j]=0;g[j][i]=0;dfs(j);}}c[++reckon]=i;return;
}
int main()
{cin>>n>>m;int x,y;memset(g,0,sizeof(g));for(int i=1;i<=m;i++){cin>>x>>y;g[x][y]=1;g[y][x]=1;d[x]++;d[y]++;}int z=1;for(int i=1;i<=n;i++){if(d[i]%2==1){z=i;oddity_point++;}}dfs(z);//判断连通性if(reckon!=m+1){cout<<"NO";return 0;}//判断奇点个数if(oddity_point!=2&&oddity_point!=0){cout<<"NO";return 0;}for(int i=1;i<=reckon;i++){cout<<c[i]<<" ";}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023-12-05 Qt学习总结8

点击 <C 语言编程核心突破> 快速C语言入门 Qt学习总结 前言二十三 QSqlDatabase数据库二十四 cmake工程管理文件总结 前言 要解决问题: 学习qt最核心知识, 多一个都不学. 二十三 QSqlDatabase数据库 QSqlDatabase 是 Qt 框架中关于数据库的统一封装&#xff0c;它支持…

Kubernetes(K8s 1.27.x) 快速上手+实践,无废话纯享版(视频笔记)

视频源&#xff1a;1.03-k8s是什么&#xff1f;_哔哩哔哩_bilibili 1 基础知识 1.1 K8s 有用么&#xff1f; K8s有没有用 K8s要不要学&#xff1f; 参考资料: https://www.infoq.com/articles/devops-and-cloud-trends-2022/?itm_sourcearticles_about_InfoQ-trends-report…

PyQt下使用OpenCV实现人脸检测与识别

背景&#xff1a; 一 数字图像处理与识别警务应用模型 基于前期所学知识&#xff0c;与公安实践相结合&#xff0c;综合设计数字图像处理与识别警务应用模型,从下列4个研究课题中选择2个进行实验实现&#xff1a;图像增强与复原、人脸检测与识别、虹膜内外圆检测与分割、车牌…

Javascript-面向对象与原型

1. 编程思想 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个调用面向对象是把食物分解成一个一个对象&#xff0c;然后由对象之间分工合作 面向对象编程 1.1 面向对象与面向过程对比 2. 构造函数 3. …

想学编程,但不知道从哪里学起,应该怎么办?

怎样学习任何一种编程语言 我将教你怎样学习任何一种你将来可能要学习的编程语言。本书的章节是基于我和很多程序员学习编程的经历组织的&#xff0c;下面是我通常遵循的流程。 1&#xff0e;找到关于这种编程语言的书或介绍性读物。 2&#xff0e;通读这本书&#xff0c;把…

基于以太坊的智能合约开发Solidity(事件日志篇)

//声明版本号&#xff08;程序中的版本号要和编译器版本号一致&#xff09; pragma solidity ^0.5.17; //合约 contract EventTest {//状态变量uint public Variable;//构造函数constructor() public{Variable 100;}event ValueChanged(uint newValue); //事件声明event Log(…

java--Date、SimpleDateFormat时间类,JDK8之前的

1.Date 代表的是日期和时间 2.SimpleDateFormat 代表简单日期格式化&#xff0c;可以用来把日期对象、时间毫秒值格式化成我们想要的形式。 3.时间格式常见符号 4.SimpleDateFormat解析字符串时间成为日期对象

Matlab数学建模算法之小波神经网络详解

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f497; 大家…

NR Channel raster和Sync raster

NR中&#xff0c;由于信道带宽可能非常大&#xff0c;如果UE按照channel Raster进行同步信号搜索&#xff0c;需要的时间很长&#xff0c;且非常耗电&#xff1b;因而NR引入了Synchronization raster的概念&#xff0c;同步信号按照Sync Raster放置。 ARFCN 频点号对应Channel…

打造Github首页的动态飞线效果

一、导语 Github首页的地球动态飞线&#xff0c;大家都比较熟悉吧 二、分析 由大量随机的3点构造出贝塞尔曲线&#xff0c;然后开始从起点到终点的飞行后&#xff0c;然后再从起点到终点的消失&#xff0c;就此完成整个过程 三、基础代码 createCurve(startPoint, endPoint…

Java 8 新特性深度解析:探索 Lambda 表达式、Stream API 和函数式编程的革新之路

Java8 新特性 Java 8 的革新之路 自 1995 年首次发布以来&#xff0c;Java 已经成为世界上最广泛使用的编程语言之一。随着时间的推移&#xff0c;Java 经历了多次版本更新&#xff0c;其中最具里程碑意义的便是 Java 8 的发布。这个版本引入了许多重大变革&#xff0c;包括 …

LabelImg的使用及注意事项

LabelImg是一款开源的图像标注工具&#xff0c;它主要用于标注目标检测、语义分割和图像分类等深度学习中需要的数据集。通过使用LabelImg&#xff0c;用户可以快速、准确地为图片中的目标添加标注信息&#xff0c;从而建立数据集。 使用步骤&#xff1a; 下载LabelImg&#x…