来源

一、定义

对于无向图:
  1) 设G是连通无向图,则称经过G的每条边一次并且仅一次的路径为欧拉通路;
  2) 如果欧拉通路是回路(起点和终点是同一个顶点),则称此回路为欧拉回路(Euler circuit);
  3) 具有欧拉回路的无向图G称为欧拉图(Euler graph)。
对于有向图:
  1) 设D是有向图,D的基图连通,则称经过D的每条边一次并且仅一次的有向路径为有向欧拉通路;
  2) 如果有向欧拉通路是有向回路,则称此有向回路为有向欧拉回路(directed Euler circuit);
  3) 具有有向欧拉回路的有向图D称为有向欧拉图(directed Euler graph)。

二、定理

无向图:
  无向图G存在欧拉通路的充要条件是:G为连通图,并且G**仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点**。
推论:
  1) 当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。
  2) 当G是无奇度结点的连通图时,G必有欧拉回路。
  3) G为欧拉图(存在欧拉回路)的充分必要条件是G为无奇度结点的连通图。
有向图:
  D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度差为1,另一个顶点的出度与入度之差为-1
推论:
  1) 当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度都相等时,D的有向欧拉通路必以出、入度之差为1的顶点作为始点,以出、入度之差为-1的顶点作为终点。
  2) 当D的所有顶点的出、入度都相等时,D中存在有向欧拉回路。
  3) 有向图D为有向欧拉图的充分必要条件是D的基图为连通图,并且所有顶点的出、入度都相等。

三、算法

连通性:
  采用深度搜索,如果有节点没有访问,说明不连通。

void DFS(int cur)                     //连通性的判断  是否完全访问掉
{int i ;for(i = 0; i<n; i++){if(!vis[i]&&edge[cur][i]){vis[i] = 1;DFS(i);}}
}DFS(0);for(int i =0; i<n; i++){if(!vis[i])return false;}  

欧拉图判断:

# 无向欧拉图:for(int i =0; i<n; i++){if(degree[i]%2){return false;}}
# 有向欧拉图:for (int i=0; i<n; i++)if (in[i] != out[i]){return false;}

路径查找:

// 无向图的欧拉回路, cur 点, 从 pos 点开始搜
void DFS_two(int cur,int pos)
{int i,a,b;stack[top++] = cur;for(i = pos;i<n;i++){if(edge[cur][i] != 0){edge[i][cur] = 0;edge[cur][i] = 0;degree[cur]--;degree[i]--;DFS_two(i,0);break;}}if(i==n && top<n)  // 走投无路, 而且还有边的时候, 退回一步{b = stack[--top];a = stack[--top];edge[a][b] = 1;edge[b][a] = 1;degree[a]++;degree[b]++;DFS_two(a,b+1);}}
// 有向图的欧拉回路, 在 cur 点, 从 pos 点开始搜
void DFS_first(int cur ,int pos)
{int i,a,b;stack[top++] = cur;for(i = pos;i<n;i++){if(edge[cur][i] != 0){edge[cur][i] = 0;out[cur]--;in[i]--;DFS_first(i,0);break;}}if(i==n && top<n)  // 走投无路, 而且还有边的时候, 退回一步{b = stack[--top];a = stack[--top];edge[a][b] = 1;out[a]++;in[b]++;DFS_first(a,b+1);}
}

所有代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int MAX = 60;
int edge[MAX][MAX];
int degree[MAX];
int in[MAX],out[MAX];
int n,type;                           //judge  grape 类型
int e;                                //边数
int top;                              // 栈底  初始化为 0;
int stack[MAX];                       //记录欧拉通路的路径
int vis[MAX];                         //是否已经访问;
void DFS(int cur)                     //连通性的判断  是否完全访问掉
{int i ;for(i = 0; i<n; i++){if(!vis[i]&&edge[cur][i]){vis[i] = 1;DFS(i);}}
}// 判断是否存在欧拉回路:
// 无向图中: 连通图且所有顶点度数为偶数
// 有向图中: 连通图且所有顶点的入度等于出度
bool judge()
{memset(vis,0,sizeof(vis));        //访问初始化DFS(0);for(int i =0; i<n; i++){if(!vis[i])return false;}                            //连通性的判断  是否完全访问掉if(type)                     //有向图{for (int i=0; i<n; i++)if (in[i] != out[i]){return false;}}else                           //无向图{for(int i =0; i<n; i++){if(degree[i]%2){return false;}}}return true;
}
// 有向图的欧拉回路, 在 cur 点, 从 pos 点开始搜
void DFS_first(int cur ,int pos)
{int i,a,b;stack[top++] = cur;for(i = pos;i<n;i++){if(edge[cur][i] != 0){edge[cur][i] = 0;out[cur]--;in[i]--;DFS_first(i,0);break;}}if(i==n && top<n)  // 走投无路, 而且还有边的时候, 退回一步{b = stack[--top];a = stack[--top];edge[a][b] = 1;out[a]++;in[b]++;DFS_first(a,b+1);}
}
// 无向图的欧拉回路, cur 点, 从 pos 点开始搜
void DFS_two(int cur,int pos)
{int i,a,b;stack[top++] = cur;for(i = pos;i<n;i++){if(edge[cur][i] != 0){edge[i][cur] = 0;edge[cur][i] = 0;
degree[cur]--;
degree[i]--;DFS_two(i,0);break;}}if(i==n && top<n)  // 走投无路, 而且还有边的时候, 退回一步{b = stack[--top];a = stack[--top];edge[a][b] = 1;edge[b][a] = 1;degree[a]++;degree[b]++;DFS_two(a,b+1);}}
int main()
{printf("0, 无向图    1, 有向图 : ");scanf("%d", &type);printf("输入顶点个数: ");scanf("%d",&n);memset(edge,0,sizeof(edge));memset(degree,0,sizeof(degree));  //无向图的度数memset(in,0,sizeof(in));          //有向图的入度memset(out,0,sizeof(out));        //有向图的出度while(true){int a,b;                      //边集scanf("%d %d",&a,&b);if(!(a||b))                   //  0 0 break{break;}edge[a][b] = 1;in[b]++;out[a]++;if(!type)                     // 如果是无向图{edge[b][a] = 1;degree[a]++;                   //无向图的度数degree[b]++;}}if(judge()){printf("\n一条欧拉回路: ");if(type)DFS_first(0,0);elseDFS_two(0,0);for(int i =0; i<top; i++){printf("%d",stack[i]);if(i+1!=top)printf(" -> ");}putchar('\n');}else{printf("\n不存在欧拉回路!\n");}return 0;
}

欧拉回路 欧拉通路 欧拉回路图相关推荐

  1. 欧拉图——欧拉通路和欧拉回路

    定义: 欧拉通路 (欧拉迹):通过图中每条边且只通过一次,并且经过每一顶点的通路. 欧拉回路 (欧拉闭迹):通过图中每条边且只通过一次,并且经过每一顶点的回路. 欧拉图:存在欧拉回路的图. 简单说欧拉 ...

  2. 图论 —— 图的遍历 —— 欧拉通路与欧拉回路问题

    [基本概念] 欧拉通路:通过图中所有边一次且仅一次行遍所有顶点的通路 欧拉回路:通过图中所有边一次且仅一次行遍所有顶点的回路 欧拉图:具有欧拉回路的图 半欧拉图:具有欧拉通路而无欧拉回路的图 奇度点: ...

  3. 图系列(四)欧拉通路与欧拉回路

    欧拉通路与欧拉回路 之前,写了图系列一二三,现在出四啦!这也意味着,对于图的部分,可以说50%以上常用的内容就已经过了一遍了.欧拉路的部分会稍微难一点,主要是我们要和定义打交道了.至于其他图的理论,我 ...

  4. 欧拉通路、欧拉回路、欧拉图和半欧拉图以及 Hierholzer 算法

    概念:欧拉通路(又称欧拉路径).欧拉回路.欧拉图和半欧拉图 定义 通过图中所有边恰好一次且行遍所有顶点的通路称为欧拉通路(又称欧拉路径). 通过图中所有边恰好一次且行遍所有顶点的回路称为欧拉回路. 具 ...

  5. #1176 : 欧拉路·一(欧拉通路的判定)

    #1176 : 欧拉路·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho最近在玩一个解密类的游戏,他们需要控制角色在一片原始丛林里面探险,收集道具,并找 ...

  6. 【POJ - 2337】Catenyms(欧拉图相关,欧拉通路输出路径,tricks)

    题干: A catenym is a pair of words separated by a period such that the last letter of the first word i ...

  7. ZOJ - 4122 Triangle City(最短路+欧拉通路+思维)

    题目链接:点击查看 题目大意:给出一张三角形的无向图,如下图所示 求出从点 ( 1 , 1 ) 到点 ( n , n ) 找到一条最长路,且每条边至多遍历一次,输出最长路的权值以及路径 题目分析:点 ...

  8. POJ - 2513 Colored Sticks 欧拉通路+并查集+静态树

    一开始想用map来搞,但是感觉好复杂,然后想了一下看大佬们用trie做的,感觉十分合理就敲了一发. 一开始re,数组要开到550000 只会静态的字典树,在每个根节点看是否出现过改颜色,如果没有就把该 ...

  9. nysit 42 欧拉通路(一笔画图)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=42 题目大意:给你一些点和边,问能否用一笔把这个图画出来,每条边只能画一次 思路:求是否存 ...

最新文章

  1. php %3cphp用大括号表示,整理HTML5中支持的URL编码与字符编码_html5教程技巧
  2. python【力扣LeetCode算法题库】1248- 统计「优美子数组」
  3. FLANN特征匹配(Python)
  4. 【Mysql】MySQL与Oracle的大小写问题
  5. 阿里云安装mysql5.6_yum安装mysql 5.6-阿里云开发者社区
  6. leetcode复习1
  7. Linux--网络编程
  8. java环境变量设置xp_java环境变量设置方法
  9. C语言实用算法系列之学生管理系统_单向链表内操作_选择排序
  10. ppc linux 性能,用profile和oprofile监视视linux性能!
  11. Mysql 1030 Got error -1 from storage engine 错误解决
  12. SpringBoot基础教程1-1-2 配置文件介绍
  13. [leetcode]227. 基本计算器 II
  14. 赛门铁克分家前利润暴跌
  15. 医学Meta分析是什么?如何快速完成一篇医学Meta分析,手把手复现
  16. notepad html 自动格式化代码,notepad++格式化html代码
  17. 二元函数偏导数公式_二阶偏导数公式详解
  18. linux比较两个文件md5,linux 比较两个文件夹diff不同 (diff命令, md5列表)
  19. 计算机作业怎么算工龄,EXCEL如何根据输入的入职日期自动计算工龄
  20. Ubuntu18.04 或 Windows10 配置yolov5环境并测试运行

热门文章

  1. UOJ#311. 【UNR #2】积劳成疾 动态规划
  2. 西门子博图PLC程序无法下载到PLCSIM
  3. TypeScript实现归并排序
  4. 手机拍照打卡活动制作方案,通过拍照不聚集活动,函数参数(Function parameters)是在函数定义中所列的名称。
  5. win10任务栏网络连接图标消失的解决办法
  6. matlab代码注释技巧
  7. 【IoT】物联网NB-IoT之移动oneNET平台简析
  8. 3.数据仓库之确定粒度
  9. kernel 选项详解(stlinux2.3) 2-2
  10. Python从视频中提取音频