PAT甲級1122 Hamiltonian Cycle (25分)|C++實現

陳xLヾ發表於2020-10-08

一、題目描述

原題連結
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:

在這裡插入圖片描述

​​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

二、解題思路

這道題其實知道Hamiltonian Cycle寫成序列之後的特點就可以順利做出來了,首先,要成為一個cycle,那麼前一個結點和後一個結點之間一定是連通的,此外,如果除了最後一個結點,中間某結點出現了兩次,那麼肯定也不是Hamiltonian Cycle,而且第一個數一定是要與最後一個數相同,才能構成一個環。把所有要素考慮進來,就不會錯了。

三、AC程式碼

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 220;
int G[maxn][maxn];
int main()
{
    int N, M, a, b, K, num;
    scanf("%d%d", &N, &M);
    for(int i=0; i<M; i++)
    {
        scanf("%d%d", &a, &b);
        G[a][b] = G[b][a] = 1;
    }
    scanf("%d", &K);
    vector<int> v(K);
    for(int i=0; i<K; i++)
    {
        scanf("%d", &num);
        bool flag = true, simple = true, cycle = true;
        int cnt[N+1] = {0}; //每個結點在題目給的序列中出現的次數
        for(int j=0; j<num; j++)
        {
            scanf("%d", &v[j]);
            cnt[v[j]]++;
            if(j>0 && G[v[j-1]][v[j]] != 1) flag = false;   //如果前後兩結點不相連,則不是Hamiltonian Cycle
            if(j != num-1 && cnt[v[j]] > 1) simple = false; //除了最後一個結點,如果中間某結點出現了兩次
        }
        if(v[0] != v[num - 1] || num != N+1)  cycle = false;    //如果第一個結點不等於最後一個結點,或者總數目小於結點數+1,則不是cycle
        (flag && simple && cycle) ? printf("YES\n") : printf("NO\n");
    }
    return 0;
}

相關文章