PAT甲级 1122 哈密顿回路

原题链接

哈密顿回路问题是找到一个包含图中每个顶点的简单回路。

这样的回路称为“哈密顿回路”。

在本题中,你需要做的是判断给定路径是否为哈密顿回路。

输入格式
第一行包含一个整数 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

猜你喜欢

转载自blog.csdn.net/weixin_45660485/article/details/125135557