日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

欧拉回路的基本概念

發布時間:2023/12/18 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 欧拉回路的基本概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

歐拉回路相關定義:

|| 如果圖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;///將起點放入Euler路徑中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;///這里初始化為1for(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;///將起點放入Euler路徑中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;///這里初始化為1for(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; }

總結

以上是生活随笔為你收集整理的欧拉回路的基本概念的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。