著名的“汉密尔顿(Hamilton)回路问题”是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次)。本题就要求你判断任一给定的回路是否汉密尔顿回路。
输入格式:
首先第一行给出两个正整数:无向图中顶点数 N(2<N≤200)和边数 M。随后 M 行,每行给出一条边的两个端点,格式为“顶点1 顶点2”,其中顶点从 1 到N 编号。再下一行给出一个正整数 K,是待检验的回路的条数。随后 K 行,每行给出一条待检回路,格式为:
n V1 V2 ⋯ Vn
其中 n 是回路中的顶点数,Vi 是路径上的顶点编号。
输出格式:
对每条待检回路,如果是汉密尔顿回路,就在一行中输出"YES",否则输出"NO"。
输入样例:
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
- 个数不为
(
n
+
1
)
(n+1)
(n+1)就是
false
- 首尾不相同为
false
for
模拟行走路径,如果子节点没有下一个要到达的点就false
#define debug
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif
#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#define MAXN (int(1024))
#define ll long long
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)
using namespace std;
#define show(x...) \
do { \
cout << "\033[31;1m " << #x << " -> "; \
err(x); \
} while (0)
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
namespace FastIO {
char print_f[105];
void read() { }
void print() { putchar('\n'); }
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
x = 0;
char ch = getchar();
ll f = 1;
while (!isdigit(ch)) {
if (ch == '-') f *= -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
read(oth...);
}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {
ll p3=-1;
if(x<0) putchar('-'), x=-x;
do{
print_f[++p3] = x%10 + 48;
} while(x/=10);
while(p3>=0) putchar(print_f[p3--]);
putchar(' ');
print(oth...);
}
} // namespace FastIO
using FastIO::print;
using FastIO::read;
int n, m, Q, K, a[MAXN];
bool vis[MAXN];
set<int> G[MAXN];
bool check(int ptr) { //for模拟行走路径
memset(vis, 0, sizeof(vis));
bool ret = true;
int u = a[ptr];
for(int i=ptr; i<m; i++) {
if(vis[u]) ret = false;
vis[u] = true;
int v = a[i+1];
if(!G[u].count(v)) ret = false; //当u没有子节点v就false
u = v;
}
return ret;
}
int main() {
#ifdef debug
freopen("test", "r", stdin);
// freopen("out_main", "w", stdout);
clock_t stime = clock();
#endif
read(n, m);
int u, v;
while(m --) {
read(u, v);
G[u].insert(v), G[v].insert(u);
}
read(Q);
while(Q--) {
read(m);
for(int i=1; i<=m; i++) read(a[i]);
if(m != n+1 || a[1] != a[m]) { //个数不为n+1, 或首尾不同都是false
printf("NO\n");
continue ;
}
bool ok = check(1); //从第一个位置开始check
printf("%s\n", ok ? "YES" : "NO");
}
#ifdef debug
clock_t etime = clock();
printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
return 0;
}