看了别人的代码直接看不懂,加了printf才明白
他的博客链接:https://www.cnblogs.com/crackpotisback/p/3964249.html
定理:若图G中含有Euler通路,则称图G为半欧拉图。若一个图是欧拉图或者是半欧拉图,则称该图是可以遍历的。

在这里插入图片描述
如果所有的顶点的度都为偶数,那么就可以随便指定一个点做欧拉环游
如果顶点的度为奇数的个数为2,那么欧拉通路的起点或者顶点应该为这两个顶点。
从V1开始,第一次的dfs为 v1->v2->v3->v4>v2->v6->v1,并将这些顶点依次入栈,并且每次删掉边,出栈的时候判断下该顶点还有没有其它路径,如果有的话,就要以它为顶点再找个闭迹,然后把闭迹上的点依次入栈。
v6出栈时,发现e6,e10还没被删掉,对它进行一次dfs,每次dfs就是在剩下的边找一条闭迹 v6->v4->v5->v6,并把这些顶点一次入栈。
出栈的顶点就构成了一条欧拉迹。

/*
六个顶点10条边 
6 10
1 1 
1 2 
1 6
2 3 
2 4 
2 6
3 4
4 5 
4 6
5 6
*/ 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <cstdlib>
#include <string>
#include <set>
#include <stack>
#define LL long long
#define pii pair<int,int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1000;
bool e[maxn][maxn];
int n,m;
stack<int>stk;
void dfs(int u){
    stk.push(u);
    cout<<u<<"入栈"<<endl;
    for(int i = 1; i <= n; i++){
        if(e[u][i]){
            e[u][i] = false;
            e[i][u] = false;
            cout<<u<<" "<<i<<"的边删除掉"<<endl;
            cout<<"dfs "<<i<<endl;
            dfs(i);
            cout<<"dfs "<<i<<" 结束"<<endl; 
            break;
        }
    }
}
void Fleury(int x){
    while(!stk.empty()) stk.pop();
    stk.push(x);
    cout<<x<<"起点入栈"<<endl; 
    int i;
    while(!stk.empty()){
        int u = stk.top();
        stk.pop();
        cout<<u<<"出栈"<<endl; 
        for(i = 1; i <= n; i++)
            if(e[u][i]) break;
           if(i <= n) 
           {    
               cout<<"找到边"<<u<<",并dfs它 "<<u<<endl;
            dfs(u); 
           } 
           else
           {
            printf("欧拉路径:%d \n",u);
        } 
        cout<<"一次循环结束"<<endl; 
    }
    puts("");
}
int main() {
    int u,v,cnt,degree,st;
    while(~scanf("%d %d",&n,&m)){
        memset(e,false,sizeof(e));
        for(int i = 0; i < m; i++){
            scanf("%d %d",&u,&v);
            e[u][v] = e[v][u] = true;
        }
        cnt = 0;
        st = 1;
        for(int i = 1; i <= n; i++){
            for(int j = 1,degree = 0; j <= n; j++)
            {    
                if(e[i][j]) degree++;
            } 
            if(degree&1)
            {
                st = i;
                cnt++;
            }
        }
        if(cnt == 2 || !cnt) Fleury(st);
        else puts("No Euler path");
    }
    return 0;
}
Last modification:September 18th, 2019 at 11:52 pm
如果觉得我的文章对你有用,请随意赞赏