欧拉路 (Fleury算法)
2016-04-05 19:07
260 查看
欧拉路 就是 一条路径,它满足这样的条件,走过图中的每条边,顶点经过次数不限。
下面说一下关于欧拉路的定理,说来惭愧,殷剑宏老师教的离散数学几乎都忘光了,现在用到的时候才翻开课本,发现全是书上的定理。
图中存在欧拉路,必须满足下面两个条件之一:
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;
}
下面说一下关于欧拉路的定理,说来惭愧,殷剑宏老师教的离散数学几乎都忘光了,现在用到的时候才翻开课本,发现全是书上的定理。
图中存在欧拉路,必须满足下面两个条件之一:
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;
}
相关文章推荐
- 全排列
- Mysql 安全问题
- HDU 1181
- 第五周项目2(1)
- 课堂翻译
- poj 2996 Help Me with the Game 模拟
- java反射
- TPC-H数据导入postgresql教程
- java反射
- JAVA实验二类的创建及封装
- 【Win 10 应用开发】加载外部的 srt 字幕
- qt的编译
- tomcat、servlet学习
- Cluster
- 第五周上机实践项目 项目2--游戏中的角色类(1)
- 推荐系统算法初探
- Android 6.0 权限管理详解
- CAE(Convolutional Auto-Encode) 卷积自编码
- Codeforces Round #251(Div. 2) 439B. Devu, the Dumb Guy 贪心
- 对象的一对一关系