1. 程式人生 > 實用技巧 >淺談歐拉回路

淺談歐拉回路

定義

尤拉路徑(尤拉通路):通過圖中所有邊的簡單路。(換句話說,每條邊都通過且僅通過一次)也叫”一筆畫”問題。
歐拉回路:閉合的尤拉路徑。(即一個環,保證每條邊都通過且僅通過一次)
尤拉圖:包含歐拉回路的圖。

起源

在一個圖中求解一條歐拉回路的問題,起源於尤拉提出的、著名的“七橋問題”。詳見百度百科

判定

尤拉路徑:

1.圖G是連通的,無孤立點。
2.無向圖奇點數為0或2,並且這兩個奇點其中一個為起點另外一個為終點。有向圖,可以存在兩個點,其入度不等於出度,其中一個入度比出度大1,為路徑的起點;另外一個出度比入度大1,為路徑的終點。

歐拉回路

1.圖G是連通的,無孤立點。
2.無向圖奇點數為0;有向圖每個點的入度必須等於出度。

演算法

求歐拉回路的演算法中,普遍使用的是Fleury演算法和Hierholzer演算法。由於Hierholzer演算法在時間複雜度和程式碼實現上都更優,所以這裡只介紹一下Hierholzer演算法。主要是我不會敲Fleury……

Hierholzer演算法思路

1.根據每個點的入度選擇起點。
2.運用DFS去遍歷當前節點的每一條邊,之後將該節點壓入棧中。
3.操作2接受後,棧中的元素就是一條歐拉回路。

附一下程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long

using namespace std;

int n,m,x,y,head[1200],cnt,map[1030][1030],d[1030],begin,s[1030],t;

void dfs(int k)
{
for(register int i = 1; i <= n; i++)
{
if(map
[k][i] > 0)

{
map[k][i] --;
map[i][k] --;
dfs(i);
}
}
s[++t] = k;
}

int main()
{
scanf("%d",&m);
for(register int i = 1; i <= m; i++)
{
scanf("%d%d",&x,&y);
map[x][y] ++;
map[y][x] ++;
n = max(n,x);
n = max(n,y);
d[x] ++;
d[y] ++;
}
for(register int i = 1; i <= n; i++)
{
if(d[i] % 2 == 1)
{
begin = i;
break;
}
}
if(begin == 0) begin = 1;
dfs(begin);
for(register int i = t; i >0; i--) printf("%d\n",s[i]);
printf("\n");
return 0;
}

推薦聯絡題目:騎馬修柵欄無序字母對