Fleury算法用于显示给定图的欧拉路径或欧拉电路。在此算法中,从一条边开始,它尝试通过删除先前的顶点来移动其他相邻的顶点。使用此技巧,在查找欧拉路径或电路的每一步中,图形都会变得更加简单。
我们必须检查一些规则以获得路径或电路-
该图必须是欧拉图。
当有两个边时,一个是桥,另一个是非桥,我们必须首先选择非桥。
选择起始顶点也很棘手,我们不能使用任何顶点作为起始顶点,如果图形没有奇数个顶点,我们可以选择任何一个顶点作为起始点,否则当一个顶点具有奇数个顶点时,我们必须先选择一个顶点。
findStartVert(graph) Input: The given graph. Output: Find the starting vertex to start algorithm. Begin for all vertex i, in the graph, do deg := 0 for all vertex j, which are adjacent with i, do deg := deg + 1 done if deg is odd, then return i done when all degree is even return 0 End dfs(prev, start, visited) Input: The pervious and start vertex to perform DFS, and visited list. Output: Count the number of nodes after DFS. Begin count := 1 visited[start] := true for all vertex b, in the graph, do if prev is not u, then if u is not visited, then if start and u are connected, then count := count + dfs(start, u, visited) end if end if end if done return count End isBridge(u, v) Input: The start and end node. Output: True when u and v are forming a bridge. Begin deg := 0 for all vertex i which are adjacent with v, do deg := deg + 1 done if deg > 1, then return false return true End fleuryAlgorithm(start) Input: The starting vertex. Output: Display the Euler path or circuit. Begin edge := get the number of edges in the graph //它不会在下一个初始化 recursion call v_count = number of nodes //这不会在下一个递归调用中初始化 for all vertex v, which are adjacent with start, do make visited array and will with false value if isBridge(start, v), then decrease v_count by 1 cnt = dfs(start, v, visited) if difference between cnt and v_count <= 2, then print the edge (start →‡ v) if isBridge(v, start), then decrease v_count by 1 remove edge from start and v decrease edge by 1 fleuryAlgorithm(v) end if done End
#include<iostream> #include<vector> #include<cmath> #define NODE 8 using namespace std; int graph[NODE][NODE] = { {0,1,1,0,0,0,0,0}, {1,0,1,1,1,0,0,0}, {1,1,0,1,0,1,0,0}, {0,1,1,0,0,0,0,0}, {0,1,0,0,0,1,1,1}, {0,0,1,0,1,0,1,1}, {0,0,0,0,1,1,0,0}, {0,0,0,0,1,1,0,0} }; int tempGraph[NODE][NODE]; int findStartVert() { for(int i = 0; i<NODE; i++) { int deg = 0; for(int j = 0; j<NODE; j++) { if(tempGraph[i][j]) deg++; //increase degree, when connected edge found } if(deg % 2 != 0) //when degree of vertices are odd return i; //i is node with odd degree } return 0; //when all vertices have even degree, start from 0 } int dfs(int prev, int start, bool visited[]){ int count = 1; visited[start] = true; for(int u = 0; u<NODE; u++){ if(prev != u){ if(!visited[u]){ if(tempGraph[start][u]){ count += dfs(start, u, visited); } } } } return count; } bool isBridge(int u, int v) { int deg = 0; for(int i = 0; i<NODE; i++) if(tempGraph[v][i]) deg++; if(deg>1) { return false; //the edge is not forming bridge } return true; //edge forming a bridge } int edgeCount() { int count = 0; for(int i = 0; i<NODE; i++) for(int j = i; j<NODE; j++) if(tempGraph[i][j]) count++; return count; } void fleuryAlgorithm(int start) { static int edge = edgeCount(); static int v_count = NODE; for(int v = 0; v<NODE; v++) { if(tempGraph[start][v]) { bool visited[NODE] = {false}; if(isBridge(start, v)){ v_count--; } int cnt = dfs(start, v, visited); if(abs(v_count-cnt) <= 2){ cout << start << "--" << v << " "; if(isBridge(v, start)){ v_count--; } tempGraph[start][v] = tempGraph[v][start] = 0; //remove edge from graph edge--; fleuryAlgorithm(v); } } } } int main() { for(int i = 0; i<NODE; i++) //copy main graph to tempGraph for(int j = 0; j<NODE; j++) tempGraph[i][j] = graph[i][j]; cout << "Euler Path Or Circuit: "; fleuryAlgorithm(findStartVert()); }
输出结果
Euler Path Or Circuit: 0--1 1--2 2--3 3--1 1--4 4--5 5--6 6--4 4--7 7--5 5--2 2--0