欧拉回路和欧拉路径

在一张图中,从一个点出发每条边经过且只经过一次得到的路径,如果最后回到起点,那么就是欧拉回路,如果最后没有回到起点,那么得到的就是欧拉路径。

在无向图中,欧拉路径满足的要求是,除了起点和终点以外其他点的度数都是偶数;欧拉回路满足的要求是所有点的度数都是偶数。

在有向图中,欧拉路径满足的要求是:除了起点和终点外,其他点的出度等于入度,起点的出度比入度多1,终点的入度比出度多1;在欧拉回路中,所有点的出度等于入度。

通常找欧拉路径的算法就是dfs遍历,但是这里的判重是判重边,而非判重点。而且是当一个点所有的边都遍历结束后才会将该点算入答案。我们以一个点为例,若有m条自环路径,那么每条路径出就要开一层,一直往下递归。那么时间复杂度就变成m^2,这个时间复杂度很高,所有我们由此产生优化,遍历一条边那么就把它删掉,以防后面再次遍历到这条边,产生不必要的冗余。但是这里如果仅仅通过h[u]=ne[i]来删除,后面遍历时可以生效,但是回溯到前面遍历并不是再从开头开始,所以并没有生效(或者换个角度来理解,我们的删除相当于直接将头节点的指针往后移,但是中间节点的指针是没有改变的,所以实际上前面的循环应该已经到了中间那么节点的部分,它们之间的指向关系并没有改变,仍然会产生新的递归循环)时间复杂度还是很高,那么该如何处理呢,我们这里通过传入指针来实现动态的删除。

void dfs(int u)
{for (int &i = h[u]; ~i;){if (used[i]){i = ne[i];continue;}used[i] = true;if (type == 1) used[i ^ 1] = true;int t;if (type == 1){t = i / 2 + 1;if (i & 1) t = -t;}else t = i + 1;int j = e[i];i = ne[i];dfs(j);ans[ ++ cnt] = t;}
}

我们在定义的时候定义int &i=h[u],修改i的时候,h[u]也被同步修改了,往后递归的时候,我们每次都从h[u]开始,h[u]不是一成不变的,修改i相当于修改h[u],修改h[u]相当于修改中间节点的指向,中间节点的指向关系变了,那么往前回溯的过程中就不会出现刚刚m^2的问题了。

1123. 铲雪车(活动 - AcWing)

这里有个很迷惑人的条件,铲雪的时候前进速度是20,不铲雪的时候前进速度是50,但是显然不铲雪的前提是学已经铲过了,那么就相当于这条路走了两边,当然是只走一遍更划算。每条道路的两个方向均需要铲雪,所以每条路径的出度等于入度,那么就是欧拉回路,所以我们可以保证每条路径只经过一次,所以我们统计出所有的路径再除20即可。这里的时间转化,我们可以先求出分钟数,然后再进行转化。

#include<bits/stdc++.h>
using namespace std;
int s,t;
double getd(double a,double b,double c,double d)
{double dx=a-c,dy=b-d;double res=dx*dx+dy*dy;return sqrt(res);
}
int main()
{scanf("%d%d",&s,&t);double a,b,c,d;double ans=0;while(~scanf("%lf%lf%lf%lf",&a,&b,&c,&d)){double sd=getd(a,b,c,d);ans += 2*sd;}int m=round(ans/1000/20*60);int h=m/60;m%=60;printf("%d:%02d",h,m);}

1184. 欧拉回路(活动 - AcWing)

要注意,欧拉回路和欧拉路径中是可以有孤立点的,经过所有边,不一定经过所有点,所以dfs要找一个有出边的点开始遍历/

#include<bits/stdc++.h>
using namespace std;
const int N=100010,M=400010;
int t,n,m;
int cnt;
int ans[M],used[M];
int h[N],e[M],ne[M],idx;
int din[N],dout[N];
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{for(int &i = h[u];~i;){if(used[i]){i=ne[i];continue;}used[i]=1;if(t==1) used[i^1]=1;int res;if(t==1){res=i/2+1;if(i&1) res*=-1;}else res=i+1;int j=e[i];i=ne[i];dfs(j);ans[++cnt]=res;}}
int main()
{scanf("%d%d%d",&t,&n,&m);memset(h,-1,sizeof h);for(int i=1;i<=m;i++){int a,b;scanf("%d%d",&a,&b);add(a,b);if(t==1) add(b,a);din[b]++,dout[a]++;}if(t==1){for(int i=1;i<=n;i++){if(din[i]+dout[i]&1){printf("NO");return 0;}}}else{for(int i=1;i<=n;i++){if(din[i]!=dout[i]){printf("NO");return 0;}}}for(int i=1;i<=n;i++){if(h[i]!=-1){dfs(i);break;}}if(cnt!=m) printf("NO\n");else{printf("YES\n");for(int i=cnt;i>=1;i--){printf("%d ",ans[i]);}}
}

 另外要注意我们dfs求得的路径是从终点到起点的,所以输出的时候需要倒着输出。

1124. 骑马修栅栏(1124. 骑马修栅栏 - AcWing题库)

这里我们需要输出经过的节点,同时使得在有多组解的情况下输出节点序最小的那组解。那么我们首先应该找到最小的有出边的点,从这里开始遍历,另外为了使得后面的点也是小的在前面,我们需要先遍历所有出边中连接的点编号最小的出边,那么可以用邻接矩阵来存边。

本题不确定是求欧拉回路还是欧拉路径,所以我们先找出第一个有边的点,然后遍历查找是否有度为奇数点,如果有就替换,否则就直接搜欧拉回路。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n;
int g[N][N],ans[N*N],cnt,d[N];
void dfs(int u)
{for(int i=1;i<=500;i++){if(g[u][i]){g[u][i]--,g[i][u]--;dfs(i);}}ans[++cnt]=u;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){int a,b;scanf("%d%d",&a,&b);g[a][b]++,g[b][a]++;d[a]++,d[b]++;}int s=1;while(!d[s])s++;for(int i=s;i<=500;i++){if(d[i]%2) {s=i;break;}}dfs(s);for(int i=cnt;i>=1;i--) printf("%d\n",ans[i]);}

1185. 单词游戏(活动 - AcWing)

思路:这里如果将单词视为节点显然建边太麻烦了,我们可以用之前的一个思路,在一个单词的首尾字母之间建边,这样的话就只有26个点,实现复杂度一下就降低了。

 那么就要想是建有向边还是无向边,我们要注意顺序问题,所以建的是有向边。然后实际上不用真的去搜,只需要判断一下每个点的出度入度是否符合要求,然后判断一下边是否连通。这里判断边是否连通不用dfs,我们用并查集来判断。

#include<bits/stdc++.h>
using namespace std;
const int N=30,M=200010;
int st[M];
int dout[N],din[N];
int p[N];
int find(int x)
{if(x!=p[x]) p[x]=find(p[x]);return p[x];
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);memset(st,0,sizeof st);memset(din,0,sizeof din);memset(dout,0,sizeof dout);for(int i=0;i<26;i++) p[i]=i;for(int i=1;i<=n;i++){string s;cin>>s;int a=s[0]-'a',b=s[s.size()-1]-'a';st[a]=st[b]=1;dout[a]++,din[b]++;p[find(a)]=find(b);}int flag=1,sc=0,ec=0;for(int i=0;i<26;i++){if(dout[i]-din[i]==1) sc++;else if(din[i]-dout[i]==1) ec++;else if(din[i]!=dout[i]) {flag=0;break;}}if (flag && !(!sc && !ec || sc== 1 && ec == 1)) flag = 0;int rep=-1;for(int i=0;i<26;i++){if(st[i]){if(rep==-1) rep=find(i);else if(rep!=find(i)){flag=0;break;}}}if(!flag) printf("The door cannot be opened.\n");else printf("Ordering is possible.\n");}
}

这题判断边是否连通也可以用dfs来写,只不过时间复杂度太高了,会超时,这里还是把代码放上。

#include<bits/stdc++.h>
using namespace std;
const int N=30,M=200010;
int st[M];
int dout[N],din[N];
int p[N];
int h[N],e[M],ne[M],idx;
int used[M];
int cnt;
void add(int a,int b)
{e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{for (int &i = h[u]; ~i;){if (used[i]){i = ne[i];continue;}used[i] = true;int j = e[i];i = ne[i];dfs(j);cnt++;}
}
int main()
{int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);memset(used,0,sizeof used);memset(din,0,sizeof din);memset(dout,0,sizeof dout);memset(h,-1,sizeof h);for(int i=1;i<=n;i++){string s;cin>>s;int a=s[0]-'a',b=s[s.size()-1]-'a';dout[a]++,din[b]++;add(a,b);}int flag=1,sc=0,ec=0;for(int i=0;i<26;i++){if(dout[i]-din[i]==1) sc++;else if(din[i]-dout[i]==1) ec++;else if(din[i]!=dout[i]) {flag=0;break;}}if (flag && !(!sc && !ec || sc== 1 && ec == 1)) flag = 0;if(!flag) printf("The door cannot be opened.\n");//判连通else {int s=0;while(!dout[s]) s++;for(int i=0;i<26;i++)if(dout[i]-din[i]==1){s=i;break;}dfs(s);if(cnt<n) printf("The door cannot be opened.\n");else printf("Ordering is possible.\n");}}
}

所以可以见得,判断欧拉回路和欧拉路径,只要判断度和连通性的性质满足即可,方法不唯一。

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

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

相关文章

DM数据库学习之路(十六)DEM部署DM8DPC集群

DEM部署DPC集群 DPC准备工作 在所有安装DPC服务器上部署dmagent&#xff0c;dmagent的运行环境需要依赖JAVA环境&#xff0c;JAVA版本必须为JAVA1.8。 创建用户 所有安装DPC服务器&#xff0c;手工建dmdba用户 # groupadd dinstall # useradd -g dinstall -d /home/dmdba…

并发编程之深入理解Java线程

并发编程之深入理解Java线程 线程基础知识 线程和进程 进程 程序由指令和数据组成、但这些指令要运行&#xff0c;数据要读写&#xff0c;就必须要将指令加载至CPU、数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理IO的…

Jmeter内置变量 vars 和props的使用详解

JMeter是一个功能强大的负载测试工具&#xff0c;它提供了许多有用的内置变量来支持测试过程。其中最常用的变量是 vars 和 props。 vars 变量 vars 变量是线程本地变量&#xff0c;它们只能在同一线程组内的所有线程中使用&#xff08;线程组内不同线程之间变量不共享&#…

模型转换案例学习:等效替换不支持算子

文章介绍 Qualcomm Neural Processing SDK &#xff08;以下简称SNPE&#xff09;支持Caffe、ONNX、PyTorch和TensorFlow等不同ML框架的算子。对于某些特定的不支持的算子&#xff0c;我们介绍一种算子等效替换的方法来完成模型转换。本案例来源于https://github.com/quic/qidk…

并发编程(2)基础篇-管程

4 共享模型之管程 本章内容 共享问题synchronized线程安全分析Monitorwait/notify线程状态转换活跃性Lock 4.1 共享带来的问题 4.1.1 小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff…

2024 全国水科技大会暨第二届智慧水环境管理与技术创新论坛

论坛二&#xff1a;第二届智慧水环境管理与技术创新论坛 召集人&#xff1a;刘炳义 武汉大学智慧水业研究所所长、教授 为贯彻落实中共中央国务院印发《数字中国建设整体布局规划》和国务院关于印发《“十四五”数字经济发展规划》的通知&#xff0c;推动生态环境智慧治理&…

L2 清点代码库----PTA(疑问)

上图转自新浪微博&#xff1a;“阿里代码库有几亿行代码&#xff0c;但其中有很多功能重复的代码&#xff0c;比如单单快排就被重写了几百遍。请设计一个程序&#xff0c;能够将代码库中所有功能重复的代码找出。各位大佬有啥想法&#xff0c;我当时就懵了&#xff0c;然后就挂…

docker pullpush 生成镜像文件并push 到阿里云

pull docker docker pull ultralytics/ultralytics # 拉取yolov8的镜像仓库 docker run -it ultralytics/ultralytics # 运行镜像 conda create -n gsafety python3.8 # 创建环境 source activate gsafety # 激活环境 pip install -i https://pypi.tuna.tsinghua.edu.cn/simp…

糖尿病性视网膜病变(DR)的自动化检测和分期

糖尿病性视网膜病变&#xff08;DR&#xff09;的自动化检测和分期 提出背景DR的阶段及其特征 历年解法计算机视觉方法多分类方法 新的解法深度学习方法迁移学习大模型多模型集成全流程分析 总结特征1&#xff1a;图像分割特征2&#xff1a;疾病分级特征3&#xff1a;治疗建议生…

开源模型应用落地-工具使用篇-获取文本向量(五)

一、前言 在之前学习的"开源模型应用落地-工具使用篇"系列文章中&#xff0c;我们已经学会了如何使用向量数据库。然而&#xff0c;还有一个问题一直未解决&#xff0c;那就是如何处理文本向量。在本文中&#xff0c;我们将继续深入学习关于向量的知识&#xff0c;特…

常见消息中间件

ActiveMQ 我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件&#xff0c;都是使用的这个MQ&#xff0c;但是现在用的确实不多了&#xff0c;说白了就是有些过时了。我们去它的官网看一看&#xff0c;你会发现官网已经不活跃了&#xff0c;好久才会更新一次。 它的单机吞…

2024年学习的最高薪酬编程语言

2024年学习的最高薪酬编程语言 10. Scala Scala是一种在Java虚拟机&#xff08;JVM&#xff09;上运行的函数式编程语言。它通常用于大数据处理、机器学习和后端Web开发。 关于Scala编程语言及其常见用途的要点如下&#xff1a; Scala是一种通用编程语言&#xff0c;运行在J…

mac真的安装不了vmware吗 mac如何安装crossover crossover序列号从哪里买 购买正版渠道

有些用户可能想在mac上运行一些只能在windows上运行的软件&#xff0c;比如游戏、专业软件等。这时候&#xff0c;就需要用到虚拟机技术&#xff0c;也就是在mac上安装一个可以模拟其他操作系统的软件&#xff0c;比如vmware或者crossover。那么&#xff0c;mac真的安装不了vmw…

【前端素材】推荐优质后台管理系统Xoric平台模板(附源码)

一、需求分析 当我们从多个层次来详细分析后台管理系统时&#xff0c;可以将其功能和定义进一步细分&#xff0c;以便更好地理解其在不同方面的作用和实际运作。 1. 功能层次 a. 用户管理功能&#xff1a; 用户注册和登录&#xff1a;管理用户账户的注册和登录过程。权限管…

K8S故障处理指南:网络问题排查思路

1. 前言 对于私有化环境&#xff0c;客户的网络架构&#xff0c;使用的云平台存在着各种差异&#xff0c;K8S网络可能会出现各种问题&#xff0c;此文着重讲解遇到此种问题的排查方法和思路&#xff0c;不会涉及相关网络底层技术描述. 环境说明 由于我们的k8s网络组件默认使…

5.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-测试需求与需求拆解

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;模拟游戏登陆器启动游戏并且完成注入 首先正常分析软件程序有没有漏洞&#xff0c;需要通过它的操作侵入&#xff0c;比如买东西&#xff0c;就通过买东西的按钮它背后有源代码就看源代码&#xff0c…

【PythonGIS】基于Python融合矢量数据(多面合一)

之前发过使用批量合并矢量数据的文章&#xff1a;【Python&GIS】基于Python批量合并矢量数据&#xff0c;正好前段时间有需求把矢量数据进行融合&#xff0c;然后就编了一段融合矢量数据的代码。今天就和大家分享一下如何使用Python对矢量数据实现融合的操作。 1.定义 首先…

基于Embedding召回和DSSM双塔模型

文章目录 基于Embedding召回介绍基于Embedding召回算法分类I2I召回U2I召回 DSSM模型DSSM双塔模型层次 基于Embedding召回介绍 基于embedding的召回是从内容文本信息和用户查询的角度出发&#xff0c;利用预训练的词向量模型或深度学习模型&#xff0c;将文本信息转换成向量进行…

三、创建脚手架和脚手架分析

三、创建脚手架 一、环境准备 1、安装node.js **下载地址&#xff1a;**https://nodejs.org/zh-cn/界面展示 2、检查node.js版本 查看版本的两种方式 node -vnode -version 出现版本号则说明安装成功&#xff08;最新的以官网为准&#xff09; 3、为了提高我们的效率&…

深度学习从入门到不想放弃-7

上一章的内容 深度学习从入门到不想放弃-6 (qq.com) 今天讲的也算基础(这个系列后来我一寻思,全是基础 ),但是可能要着重说下,今天讲前向计算和反向传播,在哪儿它都永远是核心,不管面对什么模型 前向计算: 有的叫也叫正向传播,正向计算的,有的直接把前向的方法梯度下…