哈密顿回路:通过图的每个节点一次。
存在哈密顿回路的图就是哈密顿图。
判定条件:图中任意两个不同的节点的度数之和大于等于n。
代码:求hamilton回路
void Hamilton(int ans[maxn], bool map[maxn][maxn], int n) {
int s=1, t;
int i, j;
int ansk = 2;
int w;
int temp;
bool vis[maxn];
memset(vis, false, sizeof(vis));
for (i=1; i<=n; i++)
if (map[s][i])
break;
t = i;
ans[0] = s;
ans[1] = t; //任找两个相邻的节点
while (1) {
while (1) { //从t开始拓展,拓展到一个点,就从该点在拓展
for (i=1; i<=n; i++) {
if (map[t][i] && !vis[i]) {
vis[i] = true;
ans[ansk++] = i;
t = i;
break;
}
}
if (i > n)
break;
}
reverse(ans, 0, ansk-1); //翻转
temp = s;
s = t;
t = temp;
while (1) { //从刚开始的s再拓展
for (i=1; i<=n; i++) {
if (map[t][i] && !vis[i]) {
vis[i] = true;
ans[ansk++] = i;
t = i;
break;
}
}
if (i > n) break;
}
if (!map[s][t]) { //若没有形成环,就构造一个环。
for (i=1; i<ans-2; i++)
if (map[ans[i][t]] && map[ans[i+1][s]])
break;
w = ansk-1;
i++;
t = ans[i];
reverse(ans, i, w);
}
if (ansk == n) //完成停止
return ;
for (j=1; j<=n; j++) { //加环以外的边。
if (!vis[j]) {
for (i=1; i<ansk-1; i++)
if (map[ans[i]][j])
break;
if (map[ans[i]][j])
break;
}
}
s = ans[i-1];
t = j;
reverse(ans, 0, i-1); //始终形成环
reverse(ans, i, ansk-1);
ans[ansk++] = j;
vis[j] = true;
}
}