生活随笔
收集整理的這篇文章主要介紹了
欧拉回路的基本概念
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
歐拉回路相關定義:
|| 如果圖G(有向圖或者無向圖)中有一條通路,該通路上所有邊一次且僅有一次行遍所有頂點,那么這條通路稱為歐拉通路
|| 如果圖G中所有邊一次且僅有一次行遍所有頂點,稱圖G有歐拉回路
|| 具有歐拉回路的圖稱為歐拉圖,不具有歐拉回路但具有歐拉通路的圖稱為半歐拉圖
歐拉回路的定理和推論:
|| 無向圖G存在歐拉通路的充要條件為: G為連通圖,且G有0或2個奇度節點( 度數為奇度的節點)
|| 推論1:當無向圖G只有兩個奇度節點時,那么其中的歐拉通路以這兩個節點為端點
|| 推論2:當無向圖G沒有奇度節點時,那么G必有歐拉回路
|| 推論3:無向圖G為歐拉圖的充要條件是:G為連通圖,且G有0個奇度節點
|| 有向圖G存在歐拉通路的充要條件為:(為了好記憶把出度入度不相等的點命名為“異點”)
D為有向圖,D的基圖連通,并且所有頂點的出度與入度都相等;或者除兩個頂點外,其余頂點的出度與入度都相等,而這兩個頂點中一個頂點的出度與入度之差為1,另一個頂點的出度與入度之差為-1。
|| 簡化:D為連通有向圖,且有0個或者2個異點(且這兩兩個異點的出入度差分別為±1)
|| 推論1: 當D除出、入度之差為1,-1的兩個頂點之外,其余頂點的出度與入度都相等時,D的有向歐拉通路必以出、入度之差為1的頂點作為始點,以出、入度之差為-1的頂點作為終點。
|| 推論2: 當D的所有頂點的出、入度都相等時,D中存在有向歐拉回路。
|| 推論3: 有向圖D為有向歐拉圖的充分必要條件是D的基圖為連通圖,并且所有頂點的出、入度都相等。
歐拉回路的求解
|| DFS搜索求解歐拉回路:
基本思路:利用歐拉定理判斷出一個圖存在歐拉回路或歐拉通路后,選擇一個正確的起始頂點,用DFS算法遍歷所有的邊(每一條邊只遍歷一次),遇到走不通就回退。在搜索前進方向上將遍歷過的邊按順序記錄下來。這組邊的排列就組成了一條歐拉通路或回路。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std
;
int ans
[200];
int top
;
int N
,M
;
int mp
[200][200];
void dfs(int x
)
{int i
;top
++;ans
[top
]=x
;for (i
=1; i
<=N
; i
++){if(mp
[x
][i
]>0){mp
[x
][i
]=mp
[i
][x
]=0;dfs(i
);break;}}
}void fleury(int x
)
{int brige
,i
;top
=1;ans
[top
]=x
;while(top
>=0){brige
=0;for (i
=1; i
<=N
; i
++) {if(mp
[ans
[top
]][i
]>0){brige
=1;break;}}if (!brige
){printf("%d ", ans
[top
]);top
--;}else {top
--;dfs(ans
[top
+1]);}}
}int main()
{int x
,y
,deg
,num
,start
,i
,j
;scanf("%d%d",&N
,&M
);memset(mp
,0,sizeof (mp
));for(i
=1;i
<=M
; i
++){scanf("%d%d",&x
,&y
);mp
[x
][y
]=1;mp
[y
][x
]=1;}num
=0;start
=1;for(i
=1; i
<=N
; i
++){deg
=0;for(j
=1; j
<=N
; j
++){deg
+=mp
[i
][j
];}if(deg
%2==1){start
=i
;num
++;}}if(num
==0||num
==2){fleury(start
);}else{puts("No Euler path");}return 0;
}
|| Fleury(佛羅萊)算法:(算法的關鍵是:能不走橋就不去走橋,實在無路可走了才去走橋)
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std
;
int ans
[200];
int top
;
int N
,M
;
int mp
[200][200];
void dfs(int x
)
{int i
;top
++;ans
[top
]=x
;for (i
=1; i
<=N
; i
++){if(mp
[x
][i
]>0){mp
[x
][i
]=mp
[i
][x
]=0;dfs(i
);break;}}
}void fleury(int x
)
{int brige
,i
;top
=1;ans
[top
]=x
;while(top
>=0){brige
=0;for (i
=1; i
<=N
; i
++) {if(mp
[ans
[top
]][i
]>0){brige
=1;break;}}if (!brige
){printf("%d ", ans
[top
]);top
--;}else {top
--;dfs(ans
[top
+1]);}}
}int main()
{int x
,y
,deg
,num
,start
,i
,j
;scanf("%d%d",&N
,&M
);memset(mp
,0,sizeof (mp
));for(i
=1;i
<=M
; i
++){scanf("%d%d",&x
,&y
);mp
[x
][y
]=1;mp
[y
][x
]=1;}num
=0;start
=1;for(i
=1; i
<=N
; i
++){deg
=0;for(j
=1; j
<=N
; j
++){deg
+=mp
[i
][j
];}if(deg
%2==1){start
=i
;num
++;}}if(num
==0||num
==2){fleury(start
);}else{puts("No Euler path");}return 0;
}
總結
以上是生活随笔為你收集整理的欧拉回路的基本概念的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。