7-1 Hamiltonian Cycle
The “Hamilton cycle problem” is to find a simple cycle that contains every vertex in a graph. Such a cycle is called a “Hamiltonian cycle”.
In this problem, you are supposed to tell if a given cycle is a Hamiltonian cycle.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive integers
N
(
2
<
N
≤
200
)
N (2<N≤200)
N(2<N≤200), the number of vertices, and
M
M
M, the number of edges in an undirected graph. Then
M
M
M lines follow, each describes an edge in the format Vertex1 Vertex2
, where the vertices are numbered from 1 to
N
N
N. The next line gives a positive integer
K
K
K which is the number of queries, followed by
K
K
K lines of queries, each in the format:
n
V
1
V
2
.
.
.
V
n
n \ V_1\ V_2\ ... \ V_ n
n V1 V2 ... Vn
where n
is the number of vertices in the list, and
V
i
′
s
V _i's
Vi′s are the vertices on a path.
Output Specification:
For each query, print in a line YES
if the path does form a Hamiltonian cycle, or NO
if not.
Sample Input:
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
Sample Output:
YES
NO
NO
NO
YES
NO
#include <stdio.h>
#include <string.h>
#define MAXN 201
typedef enum {false, true} bool;
int G[MAXN][MAXN] = {0};
int Ne = 0, Nv = 0;
void BuildGraph(void);
bool IsHamiltonianCycle(int *v, int n);
int main()
{
// 建立图,用邻接矩阵还是用邻接表?
// 依据操作,判断两个节点之间是否存在边,并且每一个节点是否只经过一次
BuildGraph();
int k;
scanf("%d", &k);
for (int i = 0; i < k; i++) {
int n;
scanf("%d", &n);
int v[n + 1];
for (int j = 1; j <= n; j++) {
scanf("%d", &v[j]);
// printf("v[%d] = %d ", j, v[j]);
}
if (IsHamiltonianCycle(v, n) == true) {
puts("YES");
}
else {
puts("NO");
}
}
return 0;
}
void BuildGraph(void)
{
scanf("%d%d", &Nv, &Ne);
int v1, v2;
for (int i = 1; i <= Ne; i++) {
scanf("%d%d", &v1, &v2);
G[v1][v2] = 1;
///
G[v2][v1] = 1;
}
}
// 判断是否是哈密顿回路
// 给定k和一些数,判断
// 哈密顿回路需要满足以下条件
// 1. 第一个数肯定等于节点数 + 1
// 2. 第一个节点和最后一个节点相同
// 3. 第一个至K-1个节点必须遍历所有的K-1(即n)个节点,如果发现有重复,可break
bool IsHamiltonianCycle(int *vertices, int n)
{
if (n != Nv + 1) {
return false;
}
// vertices从1开始
if (vertices[1] != vertices[n]) {
return false;
}
// printf("here1 n=%d ", n);
// vertices[1]与vertices[n]首尾相等
int visit[n + 1];
memset(visit, 0, sizeof(visit));
// for (int j = 1; j <= n; j++) {
// printf("%d ", visit[j]);
// }
int i = 1;
while (i != n) {
int v1 = vertices[i];
int v2 = vertices[i + 1];
// printf("G[%d][%d] = %d visit[v1] = %d ", v1, v2,G[v1][v2], visit[v1]);
if (G[v1][v2] == 1 && visit[v1] == 0) {
visit[v1] = 1;
i++;
continue;
}
else {
return false;
}
}
return true;
}