Fleury算法 -求无向欧拉图的欧拉回路


背景介绍

1) 欧拉图:存在经过图中每条边恰好一次并且仅一次行遍所有点的回路

  • 通俗来说,该回路有两个特点:
    • 边:包括图中所有边(不重复地)
    • 点:包括图中所有点(可重复地)

2) 欧拉图判断:不存在奇度顶点

  • 通俗来说,图中每个顶点与偶数条边相连

3) 欧拉回路求解:判断一个图是欧拉图,下一步就会问这条回路具体是什么,Fleury算法就是用来找出无向欧拉图可能的的欧拉回路

4) Fleury算法

  1. 任意选择图中的一个顶点作为初始顶点a1
  2. 优先选择走非桥(删除该边后不会连通分支不会增加,逼不得已再走桥。按照与该点连接边数判断:
    2.1 a1与某个点有两条边相连=>这两条边必为非桥
    2.2 a1与某个点仅一条边相连:皆有可能(是否可能存在a1分别与a2、a3仅有一条边,边(a1,a2)为桥,而(a1,a3)非桥???)
  3. 若是未走完所有边,继续第二步

5)实现代码C++

#include<iostream>
using namespace std;
//该算法适用于无向欧拉图找出具体的欧拉通路 
int main()
{
	int n;
	cout<<"please input the order of metrix: ";
	cin>>n;
	
	int a[n+1][n+1];
	for(int i=1;i<=n;i++)//使用邻接矩阵表示图 
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
		}
	}
	
	int start=1,present=start,tmp=0;
	//算法思想:能不走桥就不走桥 
	while(true)
	{
		int flag2=0,flag1=0; 
		
		for(int j=1;j<=n;j++)//遍历该点与其它所有点的邻接关系 
		{
			if(a[present][j]>=2)//找到第一条非桥,就走它 
			{
				flag2++;//记录是否存在非桥 
				a[present][j]--;//边是二元关系,两个点都要改变;包括了环的情况 
				a[j][present]--;
				cout<<"("<<present<<","<<j<<")"<<" ";//模拟走的道路 
				present=j;//更新当前点 
				break;//找到就进入下一个点 
			}
			if(a[present][j]==1&&flag1==0)//记录第一个与当前点存在一条边(不一定是割边)的点 
			{
				flag1++;
				tmp=j;
			}
	
		}
		
		if(flag2==0&&flag1==1)//只能走桥 
		{
			a[present][tmp]--;
			a[tmp][present]--;
			cout<<"("<<present<<","<<tmp<<")"<<" ";
			present=tmp; 
			
		} 
		if(flag2==0&&flag1==0)break;//当矩阵为零矩阵时结束 
	}
	 
	 
	 return 0;
	
}

6)测试用例

2(图有两个点,对应矩阵的阶为2)
0 2
2 0

3
0 2 2
2 0 2
2 2 0

3
0 2 0
2 0 2
0 2 0

3
0 0 2
0 0 2
2 2 0

4 (第一个点有一个环)
2 0 1 1
0 0 1 1
1 1 0 0
1 1 0 0


收获

  • 使用矩阵这个强大的工具表示图,对图的操作,如增删边,找回路等都可以有矩阵相应计算完成
  • 把思路理清楚后再用代码实现,编程时注意标记重置的位置


版权声明:本文为qq_40738840原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>