欧拉路 就是 一条路径,它满足这样的条件,走过图中的每条边,顶点经过次数不限。
下面说一下关于欧拉路的定理,说来惭愧,殷剑宏老师教的离散数学几乎都忘光了,现在用到的时候才翻开课本,发现全是书上的定理。
图中存在欧拉路,必须满足下面两个条件之一:
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;
}