欧拉路 (Fleury算法)

欧拉路 就是 一条路径,它满足这样的条件,走过图中的每条边,顶点经过次数不限。

下面说一下关于欧拉路的定理,说来惭愧,殷剑宏老师教的离散数学几乎都忘光了,现在用到的时候才翻开课本,发现全是书上的定理。

图中存在欧拉路,必须满足下面两个条件之一:

1.图中所有点的度数都为偶数

2.图中只有两个点的度数为奇数


至于Fleury的算法思想,我就不想写了,网上都有,反正我没有看懂。。图论的知识真是太博大精深了,

下面上模板,输出顺序是字典序。


#include <iostream>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAX 100
bool map[MAX][MAX];
int path[MAX];
stack<int>s;
int n,m;
int cnt;

void dfs(int x){
    s.push(x);
    for(int i=1;i<=n;i++){
        if(map[x][i]>0){
            map[i][x] = map[x][i] = 0;   //删除该边
            dfs(i);
            break;
        }
    }
}

void Fleury(int v){
    while(!s.empty())
        s.pop();
    s.push(v);
    while(!s.empty()){
        int b = 0;
        for(int i=1;i<=n;i++){
            if(map[s.top()][i]>0){
                b = 1;
                break;
            }
        }
        if(b == 0){  //没有相关联的边
            path[cnt++] = s.top();
            s.pop();
        }
        else{
            int y = s.top();
            s.pop();
            dfs(y);   //如果存在边的话,就深度遍历
        }
    }
    cout<<endl;
}

int main(){
    int i,j,a,b;
    cin>>n>>m;
    memset(map,0,sizeof(map));
    for(i=0;i<m;i++){
        cin>>a>>b;
        map[a][b] = map[b][a] = 1;
    }
    int start = 1;
    int num = 0;
    for(i=1;i<=n;i++){
        int degree = 0;
        for(j=1;j<=n;j++){
            degree += map[i][j];
        }
        if(degree%2){    //如果是奇数
            if(num == 0)
                start = i;
            num++;
        }
    }
    cnt = 0;
    if(num==0 || num==2)
        Fleury(start);
    else
        cout<<-1<<endl;
    for(i=cnt-1;i>=0;i--){  //倒序输出
        cout<<path[i]<<" ";
    }
    return 0;
}


你可能感兴趣的:(C++,算法,数学,DFS,CCF)