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