一、Hierholzer 算法
① 对于全部偶数度数的图来说,起始节点是任意的。
② 如果存在奇数点,那么一定从奇数点开始。
③ 如果存在两个奇数点,那么一定从一个奇数点开始一个奇数点结束。
P2731 [USACO3.3]骑马修栅栏 Riding the Fences
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAXN 505
int n, m, point=0x3f3f3f3f, cnt;
int ans[MAXN], in[MAXN];
int Map[MAXN][MAXN];
void dfs(int u)
{
for(int i=1;i<=m;i++)
{
if(Map[u][i])
{
Map[u][i]--;
Map[i][u]--;
dfs(i);
}
}
ans[++cnt] = u;
}
int main(void)
{
cin >> n;
for(int i=1;i<=n;i++)
{
int u,v;
cin >> u >> v;
m = max(m, max(u, v));
Map[u][v]++;
Map[v][u]++;
in[u]++;
in[v]++;
point = min(point, min(u, v));
}
for(int i=1;i<=m;i++)
{
if(in[i] & 1)
{
point = i;
break;
}
}
dfs(point);
for(int i=cnt;i>=1;i--)
cout << ans[i] << endl;
return 0;
}
二、Fleury 算法
算法流程:
- 任取 v 0 ∈ V ( G ) v_0\in V(G) v0∈V(G) ,令 P 0 = X 0 P_0 = X_0 P0=X0
- 设
p
i
=
v
0
e
1
v
1
e
2
⋯
e
i
v
i
p_i =v_0\ e_1\ v_1\ e_ 2\cdots e_i\ v_i
pi=v0 e1 v1 e2⋯ei vi 是已经遍历过的边,现在要从
E
(
G
)
−
(
e
1
e
2
e
3
⋯
e
i
)
E(G)-(e_1\ e_2\ e_3\cdots\ e_i)
E(G)−(e1 e2 e3⋯ ei) 中选取
e
i
+
1
e_{i+1}
ei+1 ,选取规则如下:
- e i + 1 e_{i+1} ei+1 与 v i v_i vi 相连。
- 除非没有别的边可以走,否则 e i e_i ei 不应该是 G i = G − ( e 1 e 2 e 3 ⋯ e i ) G_i = G-(e_1\ e_2\ e_3\cdots\ e_i) Gi=G−(e1 e2 e3⋯ ei) 的桥。
- 当第二部无法进行时,算法停止。
从算法的实现流程就可以看出,这个算法效率低下,所以我就不写了(其实是不会