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;
}
View Code

 

posted @ 2017-04-30 16:49  辰曦~文若  阅读(1922)  评论(0编辑  收藏  举报