Fleury算法求歐拉路徑
列出一些有關歐拉的題
混合圖歐拉回路 poj1637,zju1992,hdu3472
郵遞員問題 poj2040 poj2404
哈密頓迴路 poj2439 poj2288 poj1392 hdu2894
3018
1116
2894
1956
3472
求歐拉回路的fleury算法 可求重邊
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 1005;
int n, m, flag, top, sum, du[N], ans[5005], map[N][N];
void dfs(int x)
{
ans[++top] = x;
for(int i = 1; i <= n; i++)
{
if(map[x][i] >= 1)
{
map[x][i]--;
map[i][x]--;
dfs(i);
break;
}
}
}
void fleury(int x)
{
top = 1;
ans[top] = x;
while(top > 0)
{
int k = 0;
for(int i = 1; i <= n; i++)//判斷是否可擴展
{
if(map[ans[top]][i] >= 1)//若存在一條從ans[top]出發的邊 那麼就是可擴展
{k = 1; break;}
}
if(k == 0)//該點x沒有其他的邊可以先走了(即不可擴展), 那麼就輸出它
{
printf("%d ", ans[top]);
top--;
}
else if(k == 1)//如可擴展, 則dfs可擴展的哪條路線
{
top--;//這需要注意
dfs(ans[top+1]);
}
}
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
memset(du, 0, sizeof(du));
memset(map, 0, sizeof(map));
for(int i = 1; i <= m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
map[x][y]++; //記錄邊, 因爲是無向圖所以加兩條邊, 兩個點之間可能有多條邊
map[y][x]++;
du[x]++;
du[y]++;
}
flag = 1; // flag標記開始點。 如果所有點度數全爲偶數那就從1開始搜
sum = 0;
for(int i = 1; i <= n; i++)
{
if(du[i] % 2 == 1)
{
sum++;
flag = i;// 若有奇數邊, 從奇數邊開始搜
}
}
if(sum == 0 || sum == 2)
fleury(flag);
}
return 0;
}