哈密顿回路问题是找到一个包含图中每个顶点的简单回路。
这样的回路称为“哈密顿回路”。
在本题中,你需要做的是判断给定路径是否为哈密顿回路。
输入格式
第一行包含一个整数 N 表示顶点数,一个整数 M 表示给定无向图中的边数。接下来 M 行,每行包含两个整数 a,b,表示点 a 和 b 之间存在一条边。
所有顶点编号从 1 到 N。
再一行给出整数 K,表示询问次数。
接下来 K 行,每行包含一个询问,格式如下:
n V1 V2 … Vn
n 表示给定路径经过的点的数目,Vi 是路径中经过的点。输出格式
对于每个询问,如果是哈密顿回路则在一行输出 YES,否则输出 NO。数据范围
2<N≤200,
N−1≤M≤N(N−1)2,
1≤K≤1000,
1≤n≤410
输入样例:
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
我的解法:
#include <bits/stdc++.h>
using namespace std;
const int N = 201;
int nodes[N * 2];
bool g[N][N], st[N];
int n, m;
bool check(int cnt){
// 环路头尾是否相等, 环路节点数量是否为节点数+1
if(nodes[0] != nodes[cnt - 1] || cnt != n + 1) return false;
memset(st, 0, sizeof st);
// 环路上的边是否存在
for(int i = 0; i < cnt - 1; i ++ ){
st[nodes[i]] = true;
if(!g[nodes[i]][nodes[i + 1]]) return false;
}
// 每一个节点是否都遍历到了
for(int i = 1; i <= n; i ++ ){
if(!st[i])
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;
for(int i = 0; i < cnt; i ++ ){
cin >> nodes[i];
}
if(check(cnt)) puts("YES");
else puts("NO");
}
return 0;
}
收获:
哈密顿回路需要满足以下四个条件:
1、 环路起点与终点相同
2、每一步都有边
3、所有点都能走到
4、环路节点数为n+1