原题【传送门】
该题为求解欧拉路的问题。

一、背景知识

欧拉路:给定无孤立节点的图G,若存在一条路,经过图中每一边一次且仅一次,则该路称为欧拉路。
欧拉回路:若存在一条回路,经过图中的每一边一次且仅一次,则该回路称为欧拉回路。
欧拉图:具有欧拉回路的图称为欧拉图。
判定定理:无向图G具有一条欧拉路,当且仅当G是连通的,且有0个或2个奇数度结点。
--------以上来自左孝凌的《离散数学》

二、题目分析

给定一个图,存在欧拉路,则依次输出其经过结点;如果存在多条,则输出字典序最小的;如果不存在,则输出-1;
由于欧拉回路是一种特殊的欧拉路,所以判定定理仍然有效。题目中没有特殊要求是回路,则都按照欧拉路处理即可。
由判定定理,需要先判断:是连通图且只有0或2个奇数度结点。判断连通图可用并查集实现。
接着采用Hierholzer 算法求出欧拉路。

三、Hierholzer 算法

递归思路:
1.判断奇点数。奇点数若为0则任意指定起点,奇点数若为2则指定起点为奇点。
2.开始递归函数Hierholzer(x):
  循环寻找与x相连的边(x,u):
    删除(x,u)
    删除(u,x)
    Hierholzer(u);
  将x插入答案队列之中
3.倒序输出答案队列。

堆栈思路:
1.判断奇点数。奇点数若为0则任意指定起点,奇点数若为2则指定起点为奇点,将起点入栈。
2. 若栈不为空:
  取栈顶元素 x(区别弹栈)
  x 连接的边数为0:
   将该元素加入答案队列
   弹栈
  x 连接的边数不为0:
   寻找与其相连的边 (x,u)
   删除(x,u)
   删除(u,x)
   u入栈
3.倒序输出答案队列。

四、代码

#include<stdio.h>
#include<vector>
#include<set>
using namespace std;
int n,m;
const int maxn=10001;
set<int> edges[maxn];//set自然成升序,每次取出第一个即可。
vector<int> ans;
int father[maxn];
int find_father(int s){//寻找祖宗int a=s;while(father[a]!=a){//找到祖宗为:aa=father[a];}while(s!=a){//回溯,减小高度进而减小时间复杂度int tmp=s;s=father[s];father[tmp]=a;}return a;
}
bool test(){//检测是否存在欧拉路int fnum=0;for(int i=1;i<=n;i++){//数连通子图的个数if(father[i]==i) fnum++;}if(fnum>1) return 0; //非联通图int num=0;for(int i=1;i<=n;i++){//奇数节点个数if(edges[i].size() %2==1){ //更好的写法:if(edges[i].size()&1){...}num++;}}if(num==2) {//如果是2个奇数节点,检测1是否为奇数度。if(edges[1].size()%2==1) return 1; //或者:return edges[1].size()%2else return 0;}else if(num==0) return 1;else return 0;
}
void dfs(int s){//递归写法,只有80分,爆栈while(!edges[s].empty()){int v=*edges[s].begin() ;edges[s].erase(v);edges[v].erase(s); dfs(v);  }ans.push_back(s); return;
}
void dfs1(int s){//栈写法,满分path.push_back(s);while(!path.empty() ){int cur=path.back() ;if(edges[cur].empty()){ans.push_back(cur);path.pop_back() ; }else{int v=*edges[cur].begin() ;edges[cur].erase(v);edges[v].erase(cur);path.push_back(v);              }}
}
int main(){scanf("%d%d",&n,&m);int u,v;for(int i=1;i<=n;i++){father[i]=i;}for(int i=0;i<m;i++){scanf("%d%d",&u,&v);int uf=find_father(u);int vf=find_father(v);if(uf!=vf) father[vf]=uf;//新读入的边将两个连通子图连通edges[u].insert(v);edges[v].insert(u);  }if(!test()){printf("-1"); return 0;}dfs1(1);for(int i=ans.size() -1 ;i>=0;i--){//倒序输出printf("%d ",ans[i]);}return 0;
}

五、参考与感想

欧拉回路求解算法
CCF CSP 竞赛试题——送货(201512-4)(真的100分)
第二个参考的代码真的厉害,可惜有些没看懂。
大家都看到这里了,点个赞吧,嘿嘿~

csp 201512-4 送货(hierholzer算法的递归和堆栈实现)相关推荐

  1. 201512-4 CSP 真题 送货

    201512-4 CSP 真题 送货 题目分析 学过离散数学应该对欧拉通路不陌生,这道题简单来说就是找一条欧娜通路出来,就是一笔画的问题,且要求从标号1开始,这种题只能用bfs. dfs(深度优先搜索 ...

  2. 算法之递归(3)- 链表操作

    算法之递归(3)- 链表操作 递归(2)尝试了一个单链表的遍历,同时又分析了如何添加自己的操作,是在递归调用之前,还是在递归调用之后. 今天,打算将问题深入一下,即添加相应的操作在递归的过程中. (免 ...

  3. 算法解读 ---- 递归(一)

    算法解读 ---- 递归(一) 算法的最重要的是算法设计的模型,以及该模型背后的设计思想. 定义: 递归从编程的角度上理解:递归就是一个过程或者函数在其定义中直接或间接调用自身的一种方法. 递归是一种 ...

  4. 洛谷 - P7771 【模板】欧拉路径(Hierholzer算法)

    题目链接:点击查看 题目大意:给出一个 nnn 个点 mmm 条边的有向图,需要输出字典序最小的欧拉路径 题目分析:个人感觉 Hierholzer 算法的精髓还是需要理解为什么答案是 dfs 时后序遍 ...

  5. 数据结构与算法之递归题目

    数据结构与算法之递归题目 目录 求n!的结果 汉若塔问题 打印字符串的全部子序列,包括空字符串 打印一个字符串的全部排序 1. 求n!的结果 public static long getFactori ...

  6. Java入门算法(递归篇)丨蓄力计划

    本专栏已参加蓄力计划,感谢读者支持 往期文章 一. Java入门算法(贪心篇)丨蓄力计划 二. Java入门算法(暴力篇)丨蓄力计划 三. Java入门算法(排序篇)丨蓄力计划 四. Java入门算法 ...

  7. 2.2基本算法之递归和自调用函数_数据结构与算法之5——队列和栈

    栈和队列比较简单,而且实用性非常广泛,这里主要介绍一下他们的概念和实现,在很多算法中,栈和队列的运用很重要,因此,虽然简单确是最重要的数据结构之一,必须重视. 栈是保证元素后进先出(后存入者先使用,L ...

  8. java算法的递归问题设计_java算法-递归算法思想

    递归算法是跟常见的算法思想.使用递归算法,往往可以简化代码编写,提高程序的可读性.但是,不适合的递归往往导致程序的执行效率变低. 一.递归算法基本思想 递归算法即在程序中不断反复调用自身来叨叨求解问题 ...

  9. 2.2 基本算法之递归和自调用函数 1751 分解因数 python

    http://noi.openjudge.cn/ch0202/1751/ """ 2.2 基本算法之递归和自调用函数 1751 分解因数 http://noi.openj ...

  10. 2.2 基本算法之递归和自调用函数 8758 2的幂次方表示 python

    http://noi.openjudge.cn/ch0202/8758/ """ 2.2 基本算法之递归和自调用函数 8758 2的幂次方表示 python http:/ ...

最新文章

  1. Koadic的安装和使用---http c2远控工具
  2. 【字节码插桩】Android 打包流程 | Android 中的字节码操作方式 | AOP 面向切面编程 | APT 编译时技术
  3. QT线程使用收集示例
  4. 前端面试题目汇总摘录(JS 基础篇)
  5. 3.过滤数据 ---SQL
  6. 中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-订阅主题)
  7. gcc malloc/free的质疑
  8. LeetCode 152. 乘积最大子序列(动态规划)
  9. python基础入门第0天
  10. 快手视频如何一键批量下载
  11. 【详细图文教程】Anaconda的下载及安装
  12. html5网页制作代码-我的班级网页 HTML期末大作业
  13. 从零开始搭建Vue2.0项目(二)之集成axios
  14. html 磁帖 模板,帖子编辑器预置模板
  15. 前后端分离单点登录SSO实现方案 淘宝、京东跨域获取Cookie、OAuth2、QQ客户端多种模式
  16. Android H.265硬解码EasyPlayerPro
  17. 博图 Portal v16 相关资源
  18. Reddit CEO亲自诠释内容审核的无奈
  19. Java - 反转链表
  20. 纵横字谜算法_查找字谜的算法

热门文章

  1. TUXEDO中间件介绍及应用
  2. nekohtml和htmlparser
  3. Python纯代码pdf批量快速转换成ppt
  4. 2021-01-31
  5. HTML5活动目的,完美活动策划方案指南(教你做有意思的H5方案)
  6. 将DW数据窗口导出为EXCEL文件的方法(整理)
  7. 蓝桥杯python试题_Python爬取蓝桥杯真题讲解课程
  8. 思科CCIE证书电子档下载教程
  9. foobar2000 Mac版终于来了
  10. 如何查看java安装成功_如何查看java是否安装成功