原题链接PTA | 程序设计类实验辅助教学平台 (pintia.cn)
ACwing链接 1615. 哈密顿回路 - AcWing题库
题意
从起点出发,把所有的点走一遍,再回到起点,这样的图叫哈密顿回路
此题是为了判断是否为哈密顿回路,题目不在叙述,可以看原题描述
思路
1. 用邻接矩阵来存储每个结点之间是否存在一条边,如果存在则置为 true 。
2. 判断给定的路径是否为哈密顿回路。
1)先判断首尾结点是否相同,并且给定路径结点数是否为 n+1 个点,因为首尾结点相同,所以会多出一个点。
2)然后判断该路径中每条边是否存在,并用 st 来存储出现过的结点。
3)最后再判断所有结点是否都出现过。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 300;
bool g[N][N], st[N];
int nodes[N * 2];
int n, m;
bool check(int cnt)
{
// 起点 != 终点 或 7 != 6 + 1
// 一共6个点 从起点出发,走一圈再回到起点,起点被走了两次,所以cnt = 7 n = 6
if(nodes[0] != nodes[cnt - 1] || cnt != n + 1) return false;
memset(st, 0, sizeof st); // 先把每一个点置为false 都没有走过
for(int i = 0; i < cnt - 1; i ++ )
{
st[nodes[i]] = true; // nodes的下标 0 1 2 3 4 5 6 的点置为true
if(g[nodes[i]][nodes[i + 1]] == false) return false; // 有某个两个点不相通
}
// nodes[] 里存的点 最小编号是1, 即 st[] 的最小下标是1
for(int i = 1; i <= n; i ++ ) // 从 1 号点 到 6号点 看哪个没被走过
{
if(st[i] != true) return false;
}
return true;
}
int main()
{
cin >> n >> m;
while(m -- )
{
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = true;
}
int k;
cin >> k ;
while( k -- )
{
int cnt;
cin >> cnt; // 遍历的点的总数为7, 存进nodes中的下标 0 1 2 3 4 5 6
for(int i = 0; i < cnt; i ++ ) cin >> nodes[i];
if(check(cnt)) puts("YES");
else puts("NO");
}
return 0;
}