1122 Hamiltonian Cycle
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:
Each input file contains one test case. For each case, the first line contains 2 positive integers N (2<N≤200), the number of vertices, and M, the number of edges in an undirected graph. Then M lines follow, each describes an edge in the format Vertex1 Vertex2
, where the vertices are numbered from 1 to N. The next line gives a positive integer K which is the number of queries, followed by K lines of queries, each in the format:
n V1 V2 ... Vn
where n is the number of vertices in the list, and Vi's are the vertices on a path.
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
总结:这道题目不难,对满足条件的路径输出YES,不满足的输出NO
满足条件:
①:首尾两点相同
②:不能重复访问点,且该访问的点有通路
③:所有的点都要别访问过
代码(不知道哪里错了,扣了一分):
#include <iostream>
#include <cstring>
using namespace std;
const int N=210;
int g[N][N];
int b[2*N];
int t;
bool st[N];//用于判断当前点是否被访问过
void dfs(){
if(b[0]!=b[t-1]){//首尾两点是否是相同的点
puts("NO");
return;
}
int pre=b[0],cur;
st[0]=true;//因为不会遍历第0个节点,所以这里需要先将它赋值为true,
//第一个节点会在遍历最后一个节点的时候赋值true
for(int i=1;i<t;i++){
cur=b[i];
if(g[pre][cur]==1 && !st[cur]){//判断是否通路 和该点是否被访问过
st[cur]=true;
pre=cur;
}
else{
puts("NO");
return;
}
}
bool sign=true;
for(int i=0;i<t;i++) if(!st[i]) sign=false;//是否全部的点都已经访问过了
if(sign) puts("YES");
else puts("NO");
}
int main(){
int n,m,k;
scanf("%d%d",&n,&m);
memset(g,-1,sizeof g);
for(int i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
g[a][b]=g[b][a]=1;
}
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&t);
memset(b,0,sizeof b);
memset(st,false,sizeof st);
for(int j=0;j<t;j++)
scanf("%d",&b[j]);
dfs();
}
return 0;
}
柳神代码:
满足条件:集合中是否有点重复了,是否是k个点,首尾两点是否相同,路径是否有通路
#include <iostream>
#include <set>
#include <vector>
using namespace std;
int main() {
int n, m, cnt, k, a[210][210] = {0};
cin >> n >> m;
for(int i = 0; i < m; i++) {
int t1, t2;
scanf("%d%d", &t1, &t2);
a[t1][t2] = a[t2][t1] = 1;
}
cin >> cnt;
while(cnt--) {
cin >> k;
vector<int> v(k);
set<int> s;
int flag1 = 1, flag2 = 1;
for(int i = 0; i < k; i++) {
scanf("%d", &v[i]);
s.insert(v[i]);
}
if(s.size() != n || k - 1 != n || v[0] != v[k-1]) flag1 = 0;
for(int i = 0; i < k - 1; i++)
if(a[v[i]][v[i+1]] == 0) flag2 = 0;
printf("%s",flag1 && flag2 ? "YES\n" : "NO\n");
}
return 0;
}
好好学习,天天向上!
我要考研!