Fleury演算法求歐拉回路(二)
上一篇文章當中介紹了Fleury演算法是什麼以及演算法流程,本篇文章將介紹如何用程式碼來實現求解歐拉回路。廢話不多說先來三個例子,這三個例子分別是兩個尤拉圖和一個非尤拉圖。
非尤拉圖:
圖 1
尤拉圖一:
圖 2 (此圖來自《離散數學教程》p135)
尤拉圖二:(這是一個七個點的圖,每一個點都是6條邊)
圖 3
現在我們來開始編碼,首先,建立一個二維陣列來儲存圖,然後是輸入點的個數和邊的個數,以及哪兩個點有邊。以下是程式碼片段:
#include<stdio.h> int eulerGraph[1000][1000] = {{0}};//用來儲存圖,全域性的二維陣列 int V,E;//邊以及點的個數
printf("please input the number of V (no more than 1000): \n"); scanf("%d",&V); printf("please input the number of E : \n"); scanf("%d",&E); printf("please input E : \n"); int i,j; //Init eulerGraph for(i = 0; i < V; i++) { for(j = 0; j < V; j++) { eulerGraph[i][j] = 0; } } int m,n; //create graph for (i = 0; i < E; i++) { scanf("%d %d",&m,&n); if ((m >= V) || (n >= V)) { printf("cannot more than V\n"); return 1; } eulerGraph[m][n] = eulerGraph[n][m] = 1; }
列印你的點,看看是否輸入正確:
for(i = 0; i < V; i++) {
for(j = 0; j < V; j++) {
printf("%d ",eulerGraph[i][j]);
}
printf("\n");
}
然後,判斷是否為尤拉圖:if (!isEulerGraph()) {
printf("the graph is not euler graph!\n");
return 1;
}
isEulerGraph()函式:
int isEulerGraph() { int i,j; int count = 0; for (i = 0; i < V; i++) { for (j = 0; j < V; j++) { if (1 == eulerGraph[i][j]) count++; } if (0 != count % 2 ) return 0; count = 0; } return 1; }
接下來就是Fleury演算法:
fleury();
void fleury () {
//set a start ,v0
int temp[1000] ={0};
printf("%d -> ",temp[0]);
int i = 0;
int j = 0;
int top = 0;
int bridge = 1;
int tmp;
for (i = 0; i < E; i++) {//Traversal all E
for (j = 0; j < V; j++) {
if(1 == eulerGraph[temp[top]][j]) {
eulerGraph[temp[top]][j] = eulerGraph[j][temp[top]] = 0;
//if the E is bridge,take a signal in this E,else delete this E
if(isBridge(temp[top],j)) {
tmp = j;
eulerGraph[temp[top]][j] = eulerGraph[j][temp[top]] = 1;
}
else {
top++;
temp[top] = j;
bridge = 0;
printf("%d -> ",j);
break;
}
}
}
//if bridge == 1, no another E in this V that the E is not bridge
if (bridge) {
eulerGraph[temp[top]][tmp] = eulerGraph[tmp][temp[top]] = 0;
top++;
temp[top] = tmp;
printf("%d -> ",tmp);
}
bridge = 1;
}
// for (i = 0; i < (E - 1); i++) {
// printf("%d -> ",temp[i]);
// }
// printf ("%d",temp[E-1]);
}
呼叫的isBridge函式:
首先,建立一個數組用來儲存要判斷的Vi能夠到達的點,只要數組裡面的點未遍歷完那麼就把這些點能夠到達的點,並且在陣列中還未遍歷過加進來。以下是原始碼:
int isBridge (int m, int k) {
int temp[1000] = {-1};
int i = 0;
for (i = 0; i < 1000; i++) {
temp[i] = -1;
}
int tmp = 0;
temp[tmp] = m;
int n = 0;
//判斷從m->k是否還有其他路徑
for (tmp = 0; temp[tmp] != -1; tmp++ ) {
for (i = 0; i < V; i++) {
if (eulerGraph[temp[tmp]][i] == 1 && i == k) {
return 0;//because is exist another way to k,so m->k is not bridge
}
if (eulerGraph[temp[tmp]][i] == 1 && isExist(temp,i) == 0) {//將當前的點有邊的點,前面沒有到過的點加入到陣列當中
n++;
temp[n] = i;//take new V into temp array
}
}
}
//not found k,so m->k is bridge
return 1;
}
下面是判斷之前是否已經遍歷過這個點了,陣列中是否存在
int isExist (int *temp,int m) {
int i = 0;
while (temp[i] != -1) {
if (temp[i] == m)
return 1;
i++;
}
return 0;
}
以下是測試結果和全部的原始碼:
測試非尤拉圖:
測試尤拉圖一:
測試尤拉圖二:(本人有點懶,所以就不打算使用手動輸入的方式嘍,採用輸入重定向的方式來進行輸入,大家平時測試的時候也可以這樣做,畢竟比較方便一點)
輸入:
7
21
0 1
0 2
0 3
0 4
0 5
0 6
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
輸出:
以上就是我對於Fleury演算法的理解,如果覺得還可以,請點個贊或者在下方評論,以下是我的原始碼:
/*************************************************************************
> File Name: Fleury.c
> Author: pengjinghui
> Mail: [email protected]
> Created Time: 2015年09月24日 星期四 21時56分27秒
************************************************************************/
#include<stdio.h>
int eulerGraph[1000][1000] = {{0}};//用來儲存圖,全域性的二維陣列
int V,E;//邊以及點的個數
int isEulerGraph() {
int i,j;
int count = 0;
for (i = 0; i < V; i++) {
for (j = 0; j < V; j++) {
if (1 == eulerGraph[i][j])
count++;
}
if (0 != count % 2 )
return 0;
count = 0;
}
return 1;
}
int isExist (int *temp,int m) {
int i = 0;
while (temp[i] != -1) {
if (temp[i] == m)
return 1;
i++;
}
return 0;
}
int isBridge (int m, int k) {
int temp[1000] = {-1};
int i = 0;
for (i = 0; i < 1000; i++) {
temp[i] = -1;
}
int tmp = 0;
temp[tmp] = m;
int n = 0;
//判斷從m->k是否還有其他路徑
for (tmp = 0; temp[tmp] != -1; tmp++ ) {
for (i = 0; i < V; i++) {
if (eulerGraph[temp[tmp]][i] == 1 && i == k) {
return 0;//because is exist another way to k,so m->k is not bridge
}
if (eulerGraph[temp[tmp]][i] == 1 && isExist(temp,i) == 0) {//將當前的點有邊的點,前面沒有到過的點加入到陣列當中
n++;
temp[n] = i;//take new V into temp array
}
}
}
//not found k,so m->k is bridge
return 1;
}
void fleury () {
//set a start ,v0
int temp[1000] ={0};
printf("%d -> ",temp[0]);
int i = 0;
int j = 0;
int top = 0;
int bridge = 1;
int tmp;
for (i = 0; i < E; i++) {//Traversal all E
for (j = 0; j < V; j++) {
if(1 == eulerGraph[temp[top]][j]) {
eulerGraph[temp[top]][j] = eulerGraph[j][temp[top]] = 0;
//if the E is bridge,take a signal in this E,else delete this E
if(isBridge(temp[top],j)) {
tmp = j;
eulerGraph[temp[top]][j] = eulerGraph[j][temp[top]] = 1;
}
else {
top++;
temp[top] = j;
bridge = 0;
printf("%d -> ",j);
break;
}
}
}
//if bridge == 1, no another E in this V that the E is not bridge
if (bridge) {
eulerGraph[temp[top]][tmp] = eulerGraph[tmp][temp[top]] = 0;
top++;
temp[top] = tmp;
printf("%d -> ",tmp);
}
bridge = 1;
}
// for (i = 0; i < (E - 1); i++) {
// printf("%d -> ",temp[i]);
// }
// printf ("%d",temp[E-1]);
}
int main () {
printf("please input the number of V (no more than 1000): \n");
scanf("%d",&V);
printf("please input the number of E : \n");
scanf("%d",&E);
printf("please input E : \n");
int i,j;
//Init eulerGraph
for(i = 0; i < V; i++) {
for(j = 0; j < V; j++) {
eulerGraph[i][j] = 0;
}
}
int m,n;
//create graph
for (i = 0; i < E; i++) {
scanf("%d %d",&m,&n);
if ((m >= V) || (n >= V)) {
printf("cannot more than V\n");
return 1;
}
eulerGraph[m][n] = eulerGraph[n][m] = 1;
}
for(i = 0; i < V; i++) {
for(j = 0; j < V; j++) {
printf("%d ",eulerGraph[i][j]);
}
printf("\n");
}
if (!isEulerGraph()) {
printf("the graph is not euler graph!\n");
return 1;
}
fleury();
}
相關推薦
Fleury演算法求歐拉回路(二)
上一篇文章當中介紹了Fleury演算法是什麼以及演算法流程,本篇文章將介紹如何用程式碼來實現求解歐拉回路。廢話不多說先來三個例子,這三個例子分別是兩個尤拉圖和一個非尤拉圖。 非尤拉圖: 圖 1 尤拉圖一: 圖 2 (此圖來自《離散數學教程》p135)
Fleury 演算法,求歐拉回路
基本概念: 尤拉路:通過圖中所有邊的簡單路 歐拉回路: 閉合的尤拉路 尤拉圖: 包含歐拉回路的圖 簡單的說:歐拉回路 就是經過圖(有向圖、無向圖)的每條邊一次且僅一次,回到出發點的路徑就叫歐拉回路;
jzoj5895 【NOIP2018模擬10.5】旅遊 (求歐拉回路,性質)
題目描述 分析 一個無向圖存在歐拉回路當且僅當所有的點的度數為偶數,所以需要在每一對奇點之間連一條邊然而觀察這題這題的邊權,發現所有比某條邊小的邊之和比這條邊小。那也就是說最短路必定在最小生成樹上。這就變成了最小生成樹上的配對問題。只要保證不走重邊,結果一定是一樣的。一棵子
ACM演算法之 歐拉回路
題目描述: 歐拉回路是指不令筆離開紙面,可畫過圖中每條邊僅一次,且可以回到起點的一條迴路。現給定一個圖,問是否存在歐拉回路? 輸入: 測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是節點數N ( 1 < N < 1000 )和
uva 10129 Play On Words(單詞)求歐拉回路或尤拉通路
題目:輸入n個單詞,是否可以把這些所有單詞排成一個序列,使得每個單詞的第一個字母和上一個單詞的最後一個字母想同。 有向圖歐拉回路:1,圖連通.2,所有定點入度等於出度 有向圖尤拉通路:1,圖連通.2,僅有兩個奇度定點,其中一個入度比出度大1,另一個定點出度比入度大1 思路
poj1041 John's trip (無向圖求歐拉回路方案)
John's trip Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5950 Accepted: 1946 Special Judge Description Little John
Fleury演算法 -求無向尤拉圖的歐拉回路
背景介紹 1) 尤拉圖:存在經過圖中每條邊恰好一次並且僅一次行遍所有點的迴路 通俗來說,該回路有兩個特點: 邊:包括圖中所有邊(不重複地) 點:包括圖中所有點(可重複地) 2) 尤拉圖判斷:
弗羅萊(fleury)演算法-歐拉回路生成演算法
弗羅萊演算法是生成歐拉回路的演算法之一,今天查看了許多資料,做一下記錄整理。 1、關於尤拉圖: 尤拉圖是由哥尼斯堡橋問題抽象而來的。哥尼斯堡橋問題是指在Pregel河兩岸就7座橋,問能否一次走完所有的橋並且不重複。問題如下:
HDU 3018 Ant Trip (並查集求連通塊數+歐拉回路)
http 道路 遇到 連通塊 ems ble define ant trip 註意 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3018 題目大意:有n個點,m條邊,人們希望走完所有的路,且每條道路只能走一遍。至少要將人們
歐拉回路求路徑POJ 2230
possible 圖片 pac ans close rails AI show pair Watchcow Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8841
尤拉路 歐拉回路 定理及演算法
一:無向圖 1、定義:給定無孤立結點圖G,若存在一條路,經過圖中每條邊一次且僅一次,該條路為尤拉路, 若存在一條迴路,經過圖中每邊一次且僅一次,該回路稱為歐拉回路。 具有歐拉回路的圖稱為尤拉圖。 2、定理:無向圖G具有一條尤拉路,當且僅當G是連通的,且有0
尤拉路 歐拉回路 定理及演算法
一:無向圖 1、定義:給定無孤立結點圖G,若存在一條路,經過圖中每條邊一次且僅一次,該條路為尤拉路, 若存在一條迴路,經過圖中每邊一次且僅一次,該回路稱為歐拉回路。 具有歐拉回路的圖稱為尤拉圖。
判歐拉回路或求一個圖中尤拉圖的個數
判尤拉圖兩個條件首先聯通,其次度全部為歐度。那麼就很easy了。 題目:hdoj1878 求一個圖中尤拉圖的個數。 首先通過連通性求出各個子圖,然後求子圖中奇數度的個數cnt,cnt/2為尤拉圖的
歐拉回路
put ++ .cn -1 bool ret 技術分享 代碼 can 思路 根據歐拉圖的概念來。 註意 點數為1; 有孤立點; 代碼實現 T掉的dfs... 1 #include<cstdio> 2 const int max
UVA 10196 Morning Walk(歐拉回路)
ble move eve man first pre intersect sum ons Problem H Morning Walk Time Limit 3 Seconds Kamalis a Motashotaguy. He has
[歐拉回路] poj 1300 Door Man
linker center || 是否 connect sep cto -m vector 題目鏈接: http://poj.org/problem?id=1300 Door Man Time Limit: 1000
hdu1878歐拉回路(DFS+歐拉回路)
out sin 整數 white 偶數 ret pad bottom -m 歐拉回路 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
[模板][持續更新]歐拉回路與歐拉路徑淺析
bits solution 算法 -1 要求 logs 鏈式前向星 namespace src Luogu P2731 騎馬修柵欄 Riding the Fences 題目背景 Farmer John每年有很多柵欄要修理。他總是騎著馬穿過每一個柵欄並修復它破損的地方。 題目
51nod 1967 路徑定向(不錯的歐拉回路)
cnblogs 偶數 ret mes stack ostream lin .html pre http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1967 題意: 思路: 出度=入度,這
The Necklace UVA - 10054 (無向圖的歐拉回路)
n) 兩個 logs nec get dfs lap none view The Necklace UVA - 10054 題意:每個珠子有兩個顏色,給n個珠子,問能不能連成一個項鏈,使得項鏈相鄰的珠子顏色相同。 把顏色看做點,珠子內部連一條邊,無向圖求歐拉回路。 這