基本概念及定理
1. 欧拉通路、欧拉回路、欧拉图
无向图:
1)
设G是连通无向图,则称经过G的每条边一次并且仅一次的路径为欧拉通路;
2)
如果欧拉通路是回路(起点和终点是同一个顶点),则称此回路为欧拉回路(Euler circuit);
3) 具有欧拉回路的无向图G称为欧拉图(Euler
graph)。
有向图:
1) 设D是有向图,D的基图连通,则称经过D的每条边一次并且仅一次的有向路径为有向
欧拉通路;
2)
如果有向欧拉通路是有向回路,则称此有向回路为有向欧拉回路(directed Euler circuit);
3)
具有有向欧拉回路的有向图D称为有向欧拉图(directed Euler graph)。
请思考图5.1中的无向图及有向图是否为欧拉图或有向欧拉图。
图5.1 欧拉回路及有向欧拉回路
2. 定理及推论
欧拉通路和欧拉回路的判定是很简单的,请看下面的定理及推论。
定理5.1
无向图G存在欧拉通路的充要条件是:
G为连通图,并且G仅有两个奇度结点(度数为奇数的顶点)或者无奇度结点。
推论5.1:
1) 当G是仅有两个奇度结点的连通图时,G的欧拉通路必以此两个结点为端点。
2)
当G是无奇度结点的连通图时,G必有欧拉回路。
3) G为欧拉图(存在欧拉回路)的充分必要条件是G为无奇度结点的连通图。
EXP图5.1(a)所示的无向图,存在两个奇度顶点v2和v5,所以存在欧拉通路,且欧拉通路必
以这两个顶点为起始顶点和终止顶点;该无向图不存在欧拉回路。图5.1(b)所示的无向图为欧拉
图。
定理5.2
有向图D存在欧拉通路的充要条件是:
D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余
顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度
与入度之差为-1。
推论5.2:
1)
当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度都相等时,D的
有向欧拉通路必以出、入度之差为1的顶点作为始点,以出、入度之差为-1的顶点作为
终点。
2)
当D的所有顶点的出、入度都相等时,D中存在有向欧拉回路。
3)
有向图D为有向欧拉图的充分必要条件是D的基图为连通图,并且所有顶点的出、入度
都相等。
例如图5.1(c)所示的有向图,顶点v2和v4入度和出度均为1;顶点v1的出度为2、入度为1,
二者差值为1;顶
点v3的出度为1、入度为2,二者相差为-1;所以该有向图只存在有向欧拉通路,
且必须以顶点v1为始点,以顶点v3为终点。图5.1(d)所示的有向图不存在有向欧拉通路。
1 #include
2 #include
3 #include
4 using namespacestd;5 const int MAX = 60;6 intedge[MAX][MAX];7 intdegree[MAX];8 int in[MAX],out[MAX];9 int n,type; //judge grape 类型
10 int e; //边数
11 int top; //栈底 初始化为 0;
12 int stack[MAX]; //记录欧拉通路的路径
13 int vis[MAX]; //是否已经访问;
14 void DFS(int cur) //连通性的判断 是否完全访问掉
15 {16 inti ;17 for(i = 0; i
27
28 //判断是否存在欧拉回路:29 //无向图中: 连通图且所有顶点度数为偶数30 //有向图中: 连通图且所有顶点的入度等于出度
31 booljudge()32 {33 memset(vis,0,sizeof(vis)); //访问初始化
34 DFS(0);35 for(int i =0; i
40 if(type) //有向图
41 {42 for (int i=0; i
49 {50 for(int i =0; i
61 void DFS_first(int cur ,intpos)62 {63 inti,a,b;64 stack[top++] =cur;65 for(i = pos;i
77 {78 b = stack[--top];79 a = stack[--top];80 edge[a][b] = 1;81 out[a]++;82 in[b]++;83 DFS_first(a,b+1);84 }85 }86 //无向图的欧拉回路, cur 点, 从 pos 点开始搜
87 void DFS_two(int cur,intpos)88 {89 inti,a,b;90 stack[top++] =cur;91 for(i = pos;i
104 {105 b = stack[--top];106 a = stack[--top];107 edge[a][b] = 1;108 edge[b][a] = 1;109 degree[a]++;110 degree[b]++;111 DFS_two(a,b+1);112 }113
114 }115 intmain()116 {117 printf("0, 无向图 1, 有向图 :");118 scanf("%d", &type);119 printf("输入顶点个数:");120 scanf("%d",&n);121 memset(edge,0,sizeof(edge));122 memset(degree,0,sizeof(degree)); //无向图的度数
123 memset(in,0,sizeof(in)); //有向图的入度
124 memset(out,0,sizeof(out)); //有向图的出度
125
126 while(true)127 {128 int a,b; //边集
129 scanf("%d %d",&a,&b);130 if(!(a||b)) //0 0 break
131 {132 break;133 }134 edge[a][b] = 1;135 in[b]++;136 out[a]++;137 if(!type) //如果是无向图
138 {139 edge[b][a] = 1;140 degree[a]++; //无向图的度数
141 degree[b]++;142 }143 }144 if(judge())145 {146 printf("\n一条欧拉回路:");147 if(type)148 DFS_first(0,0);149 else
150 DFS_two(0,0);151 for(int i =0; i");156 }157 putchar(‘\n‘);158 }159 else
160 {161 printf("\n不存在欧拉回路!\n");162 }163 return 0;164 }View Code
摘自《图论算法理论、实现及应用-王桂平》
原文:http://www.cnblogs.com/locojyw/p/3724562.html