Fluery算法

看了別人的代碼直接看不懂,加了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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章