PAT_A1122
PAT甲级1122.
目录
A1122
题目
样例
输入:
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个),则不是哈密顿图;如果给定的路径不相连也不是哈密顿回路;由于题目中保证结点不重复,所以需要判定是否每个结点都出现并且都出现一次,如果不满足也不是哈密顿图。
按照上述逻辑进行判定即可,其中判定结点出现并且都只出现一次,可以直接使用map去重,如果总共节点数为n+1,但是map去重后的节点数不为n,说明没有包含所有结点。
AC代码
#include<bits/stdc++.h>
using namespace std;
int G[205][205]={0}; //存放图的数据
int n,m,k;
void judge();
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
scanf("%d%d",&n,&m);
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++) //判断k组需要查验的路径
judge();
return 0;
}
void judge() //判断一组序列能不能够成一组哈密顿回路
{
int num,temp,pre,first; //pre记录前一个位置的结点值,first记录第一个位置的值
bool flag=true;
scanf("%d",&num);
if(num!=n+1){ //如果元素个数不等于节点数+1,一定构不成哈密顿回路
flag=false;
for(int i=0;i<num;i++) //过滤本组数据
scanf("%d",&temp);
}
else{
unordered_map<int,bool> mp; //结点去重
scanf("%d",&pre);
first=pre;
mp[first]=true; //读入、保存并标记第一个结点
for(int i=1;i<num;i++){ //后序读入结点,判断和前一个结点是否有路径,如果存在断链,则不是哈密顿回路
scanf("%d",&temp);
if(G[pre][temp]==0) flag=false;
pre=temp;
mp[temp]=true;
}
if(pre!=first||mp.size()!=n)//如果首尾不同或者不包含所有结点,则不是哈密顿回路
flag=false;
}
puts(flag?"YES":"NO");
}