上面是摘自圖論書上的定義。
演算法在運行過程中刪除了所有已走的路徑,也就是說途中殘留了所有沒有行走的邊。根據割邊的定義,如果在搜尋過程中遇到割邊意味著當前的搜尋路徑需要改進,即提前輸出某一個聯通子集的訪問序列,這樣就能夠保證訪問完其中聯通子圖中後再通過割邊訪問後一個聯通子圖,最後再沿原路輸出一開始到達該點的路徑。如果只有割邊可以擴充的話,只需要考慮先輸出割邊的另一部分聯通子集訪問序列。
範例圖:
代碼如下:
#include <cstdlib>#include <cstring>#include <cstdio>#include <iostream>#include <algorithm>using namespace std;/*弗羅萊演算法*/int stk[1005];int top;int N, M, ss, tt;int mp[1005][1005];void dfs(int x) { stk[top++] = x; for (int i = 1; i <= N; ++i) { if (mp[x][i]) { mp[x][i] = mp[i][x] = 0; // 刪除此邊 dfs(i); break; } }}/*9 121 51 95 35 45 82 32 44 66 76 87 88 9path:4 5 8 7 6 8 9 1 5 3 2 4 6*/void fleury(int ss) { int brige; top = 0; stk[top++] = ss; // 將起點放入Euler路徑中 while (top > 0) { brige = 1; for (int i = 1; i <= N; ++i) { // 試圖搜尋一條邊不是割邊(橋) if (mp[stk[top-1]][i]) { brige = 0; break; } } if (brige) { // 如果沒有點可以擴充,輸出並出棧 printf("%d ", stk[--top]); } else { // 否則繼續搜尋歐拉路徑 dfs(stk[--top]); } }}int main() { int x, y, deg, num; while (scanf("%d %d", &N, &M) != EOF) { memset(mp, 0, sizeof (mp)); for (int i = 0; i < M; ++i) { scanf("%d %d", &x, &y); mp[x][y] = mp[y][x] = 1; } for (int i = 1; i <= N; ++i) { deg = num = 0; for (int j = 1; j <= N; ++j) { deg += mp[i][j]; } if (deg % 2 == 1) { ss = i, ++num; printf("%d\n", i); } } if (num == 0 || num == 2) { fleury(ss); } else { puts("No Euler path"); } } return 0; }