Fleury(佛羅萊)算法


FleuryFleury算法用於解決歐拉回路的具體輸出路徑問題,在算法開始之前,我們先用一個dfsdfs來判斷這個圖是否是一個聯通塊,然后再判斷這個圖中有奇數出度的點是否只有00個或者22個,如果是00個,則存在歐拉回路,如果是兩個,則存在歐拉路徑,對於歐拉回路,我們任意選擇一個點作為dfsdfs的第一個點,對於歐拉路徑,我們選取兩個奇數出度的點中之一來作為dfsdfs的第一個點

我們在求取的時候,用棧這種數據結構

舉個例子

 

 

比如說這個圖,顯然奇數出度的點為11和22,於是我們選擇一個點,比如說選擇11,那么我們在dfs的過程中,按照dfs的順序把點的編號放進棧中,比如我們的訪問次序是12432,則把12432放入棧中,每經過一條邊,就把這條邊的正向邊反向邊打上標記表示這條路已經走過了,由於之前我們已經判過歐拉回路存在的充要條件了,所以請對這張圖保持信心,一定是可以找到歐拉回路的,於是我們的算法流程就是: 

先把1放到棧中,然后把1-2的邊的正向邊反向邊打上標記,表示已經走過了,然后再把2放到棧中,然后走2-4,打標記,4入棧,走4-3,打標記,3入棧,走3-2,打標機,2入棧,然后我們去走2的時候發現2已經無路可走了,她能走的所有邊已經被打上了標記,也就是說這個點已經沒有辦法出去了,那么什么樣的點進去了出不來呢?顯然就是我們的奇數出度的點,於是我們在這里把棧頂輸出,然后pop出去,然后回溯,每回溯到一個點都判斷這個點是否還能走其他邊,如果不能走的話,我們就輸出這個點,然后再回溯,一直到一個點有其他邊可以走,我們就把這個pop,但是不輸出,然后再重新從這個點開始dfs比如說這幅圖中,我們在dfs了2及右邊之后,左邊的1由於還有邊可以走,於是不輸出,從1再開始dfs,最后輸出的序列就是2 , 4 , 3,2,1,5 , 6 , 1

(原文:https://blog.csdn.net/NOIAu/article/details/78203851 )

#include<iostream>
#include<stack>
const int MAXN=111;
using namespace std;

stack<int>S;
int edge[MAXN][MAXN];
int n,m;

void dfs(int x){
    S.push(x);
    for(int i=1;i<=n;i++){
        if(edge[x][i]>0){
            edge[i][x]=edge[x][i]=0;//刪除此邊
            dfs(i);
            break;
        }
    }
}

//Fleury算法的實現
void Fleury(int x){
    S.push(x);
    while(!S.empty()){
        int b=0;
        for(int i=1;i<=n;i++){
            if(edge[S.top()][i]>0){
                b=1;
                break;
            }
        }
        if(b==0){
            printf("%d",S.top());
            S.pop();
        }else {
            int y=S.top();
            S.pop();
            dfs(y);//如果有,就dfs
        }
    }
    printf("\n");
}

int main(){
    scanf("%d%d",&n,&m); //讀入頂點數以及邊數
    memset(edge,0,sizeof(edge));
    int x,y;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        edge[x][y]=edge[y][x]=1;
    }
    //如果存在奇數頂點,則從奇數頂點出發,否則從頂點0出發
    int num=0,start=1;
    for(int i=1;i<=n;i++){                        //判斷是否存在歐拉回路
        int degree=0;
        for(int j=1;j<=n;j++){
            degree+=edge[i][j];
        }
        if(degree&1){
            start=i,num++;
        }
    }
    if(num==0||num==2){
        Fleury(start);
    }else
        printf("No Euler Path\n");
    return 0;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM