基础实验6-2.2 汉密尔顿回路 (25分)
著名的“汉密尔顿(Hamilton)回路问题”是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次)。本题就要求你判断任一给定的回路是否汉密尔顿回路。
输入格式:
首先第一行给出两个正整数:无向图中顶点数 N(2<N≤200)和边数 M。随后 M 行,每行给出一条边的两个端点,格式为“顶点1 顶点2”,其中顶点从 1 到N 编号。再下一行给出一个正整数 K,是待检验的回路的条数。随后 K 行,每行给出一条待检回路,格式为:
n V1 V2 ⋯ Vn
其中 n 是回路中的顶点数,Vi 是路径上的顶点编号。
输出格式:
对每条待检回路,如果是汉密尔顿回路,就在一行中输出"YES",否则输出"NO"。
输入样例:
6 10
6 2
3 4
1 5
2 5
3 1
4 1
1 6
6 3
1 2
4 5
6
7 5 1 4 3 6 2 5
6 5 1 4 3 6 2
9 6 2 1 6 3 4 5 2 6
4 1 2 5 1
7 6 1 3 4 5 2 6
7 6 1 2 5 4 3 1
输出样例:
YES
NO
NO
NO
YES
NO
采用邻接矩阵存储图。
罗列回路不是汉密尔顿回路的情况:
如果该回路的顶点中,第一个顶点不等于最后一个顶点,则一定不是汉密尔顿回路;
如果该回路的顶点中,第一个顶点等于最后一个顶点,逐个判断该回路中每两个相邻顶点的邻接矩阵内的值是否为1,若存在两个相邻顶点不连通,则一定不是汉密尔顿回路;(边不存在)
在该回路中每遇到一个顶点,就把对应的Visited数组中的元素设为1,如果某次发现遇到的元素的Visited数组对应值已经为1,则一定不是汉密尔顿回路;(重复遇到相同顶点)
如果该回路顶点遍历完后,无向图中仍有顶点未访问到,Visited数组对应值=0,则一定不是汉密尔顿回路。
C语言实现:
#include<stdio.h>
#include<stdlib.h>
struct graph //邻接矩阵存储图
{
int Nv;
int Ne;
int * * M;
};
typedef struct graph * Graph;
Graph CreateGraph(int N);
int * Visited;
int main()
{
int i;
int N, M;
scanf("%d %d", &N, &M);
Visited = (int *)malloc(N * sizeof(int));
for (i = 0; i < N; i++)
{
Visited[i] = 0;
}
Graph G;
G = CreateGraph(N);
G->Ne = M;
int v1, v2;
for (i = 0; i < M; i++)
{
scanf("%d %d", &v1, &v2);
G->M[v1 - 1][v2 - 1] = 1;//题目结点从1开始标号,我存储时从0开始存
G->M[v2 - 1][v1 - 1] = 1;
}
int K; int num, j;
int * node;
scanf("%d", &K);
for (i = 0; i < K; i++)
{
for (int k = 0; k < N; k++)
{
Visited[k] = 0;
}
scanf("%d", &num);
node = (int *)malloc(num * sizeof(int));
for (j = 0; j < num; j++)
{
scanf("%d", &node[j]);
}
if (node[0] != node[num - 1])//该回路的第一个顶点不等于最后一个顶点,不是汉密尔顿回路
{
printf("NO\n");
}
else
{
for (j = 0; j < num - 1; j++)
{
if (G->M[node[j] - 1][node[j + 1] - 1] == 0)//边不存在,不是汉密尔顿回路
{
printf("NO\n");
break;
}
if (Visited[node[j] - 1] == 0)
{
Visited[node[j] - 1] = 1;
}
else //遇到重复的相同顶点,不是汉密尔顿回路
{
printf("NO\n");
break;
}
}
if (j == num - 1)
{
int k;
for (k = 0; k < N; k++)
{
if (Visited[k] == 0) { printf("NO\n"); break; }//回路顶点遍历完后仍有顶点未被访问,不是汉密尔顿回路
}
if (k == N) { printf("YES\n"); }//否则,是汉密尔顿回路
}
}
}
return 0;
}
Graph CreateGraph(int N) //创建图
{
Graph G;
G = (Graph)malloc(sizeof(struct graph));
G->Nv = N;
G->Ne = 0;
G->M = (int * *)malloc(N * sizeof(int *));
int i, j;
for (i = 0; i < N; i++)
{
G->M[i] = (int *)malloc(N * sizeof(int));
}
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
G->M[i][j] = 0;
}
}
return G;
}