PAT甲题题解-1122. Hamiltonian Cycle (25)-判断路径是否是哈密顿回路
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~
http://www.cnblogs.com/chenxiwenruo/p/6789799.html
特别不喜欢那些随便转载别人的原创文章又不给出链接的
所以不准偷偷复制博主的博客噢~~
先来扩展一下知识
哈密顿图:
哈密顿图是一个无向图,由指定的起点通往指定的重点,途中经过所有节点有且只经过一次。
在图论中,通常指的是哈密顿回路,即经过图中所有顶点有且只有一次,最终回到出发点。
哈密顿回路为NP完全问题,暂不存在多项式内的解法。
欧拉图:
类似的有欧拉图:图中经过每天边有且只有一次,若最终回到出发点,则是欧拉回路。
判断是否存在欧拉回路,是有定理的,网上可以找找。
然而这道题给出了路径,判断是否是哈密顿回路,瞬间感觉题目档次下降了好多有没有!!!
满足了以下条件即输出YES,只要有不满足的就输出NO:
1.路径节点个数等于n+1
2.相邻点之间存在连通的边
3.前n点各只出现过1次
4.第一个节点等于最后一个节点,构成回路
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <vector> #include <cstring> #include <queue> using namespace std; const int maxn=205; int edge[maxn][maxn]; int n,m; int main() { int u,v; memset(edge,0,sizeof(edge)); scanf("%d %d",&n,&m); for(int i=0;i<m;i++){ scanf("%d %d",&u,&v); edge[u][v]=edge[v][u]=1; } int k; scanf("%d",&k); int n1; int vis[maxn]; for(int i=0;i<k;i++){ memset(vis,0,sizeof(vis)); scanf("%d",&n1); bool flag=true; //必须是n+1的顶点个数 if(n1!=n+1) flag=false; if(n1>0){ scanf("%d",&u); vis[u]=1; } int first=u; for(int j=1;j<n1;j++){ scanf("%d",&v); if(flag){ //得存在边 if(!edge[u][v]){ flag=false; //break;傻了,这里怎么会写了个break,导致一个样例过不了。虽然false,但还是要继续读取数据的 } //前n个点必须只出现过一次 if(vis[v] && j!=n1-1) flag=false; else vis[v]=1; } u=v; } //第一个点等于最后一个点 if(v!=first) flag=false; if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }