哈密顿图的判定

推荐学习资料:

http://www.cnblogs.com/Ash-ly/p/5452580.html

http://ylroki.blog.163.com/blog/static/162978871201032775322518/

https://wenku.baidu.com/view/38dd0d4714791711cd791725.html

一、定义

通过图G的每个节点一次,且仅一次的通路称为哈密顿通路

通过图G的每个节点一次,且仅一次的回路称为哈密顿回路

含有哈密顿回路的图称为哈密顿图

二、性质与判定

摘自:https://wenku.baidu.com/view/38dd0d4714791711cd791725.html

三、构造

摘自:http://ylroki.blog.163.com/blog/static/162978871201032775322518/

四、代码

输出哈密顿图的一条哈密顿回路

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 401

int n,m;

bool e[N][N];

int cnt,s,t;
bool vis[N];
int ans[N];

void read(int &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); }
}

void Reverse(int i,int j)
{
    while(i<j) swap(ans[i++],ans[j--]);
}

void expand()
{
    while(1)
    {
        int i;
        for(i=1;i<=n;++i)
            if(e[t][i] && !vis[i])
            {
                ans[++cnt]=t=i;
                vis[i]=true;
                break;
            }
        if(i>n) return;
    }
}

void Hamilton()
{
    memset(vis,false,sizeof(vis));
    cnt=0;
    s=1;
    for(t=1;t<=n;++t)
        if(e[s][t]) break;
    vis[s]=vis[t]=true;
    cnt=2;
    ans[1]=s;
    ans[2]=t;
    while(1)
    {
        expand();
        Reverse(1,cnt);
        swap(s,t);
        expand();
        if(!e[s][t])
        {
            int i;
            for(i=2;i<cnt;++i)
                if(e[ans[i]][t] && e[s][ans[i+1]]) break;
            t=ans[i+1];
            Reverse(i+1,cnt);
        }
        if(cnt==n) break;
        int j,i;
        for(j=1;j<=n;++j)
            if(!vis[j])
            {
                for(i=2;i<cnt;++i)
                    if(e[ans[i]][j]) break;
                if(e[ans[i]][j]) break;
            }
        s=ans[i-1];
        Reverse(1,i-1);
        Reverse(i,cnt);
        ans[++cnt]=j;
        t=j;
        vis[j]=true;
    }
    for(int i=1;i<=cnt;++i) printf("%d ",ans[i]);
    printf("%d\n",ans[1]);
}

int main()
{
    int u,v;
    while(1)
    {
        read(n); read(m);
        if(!n) return 0;
        memset(e,false,sizeof(e));
        while(m--)
        {
            read(u); read(v);
            e[u][v]=e[v][u]=true;
        }
        Hamilton();
    }
}

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8439160.html

时间: 2024-10-31 10:42:37

哈密顿图的判定的相关文章

POJ 2438 哈密顿回路

Children's Dining Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4730   Accepted: 754   Special Judge Description Usually children in kindergarten like to quarrel with each other. This situation annoys the child-care women. For instant,

离散数学-图论-哈密顿图及其应用

哈密顿图 一.定义概念 1.哈密顿通路 设G=<V,E>为一图(无向图或有向图).G中经过每个顶点一次且仅一次的通路称作哈密顿通路 2.哈密顿回路 G中经过每个顶点一次且仅一次的回路(通路基础上+回到起始点)称作哈密顿回路 3.哈密顿图 若G中存在哈密顿回路,则称它是哈密顿图 4.定义详解: (1)存在哈密顿通路(回路)的图一定是连通图: (2)哈密顿通路是初级通路,哈密顿回路是初级回路: (3)若G中存在哈密顿回路,则它一定存在哈密顿通路,反之不真(看课本的话,是必要条件,而不是充分条件,故

哈密顿图(Hamilton)

概念: 哈密顿图:图G的一个回路,若它通过图的每一个节点一次,且仅一次,就是哈密顿回路.存在哈密顿回路的图就是哈密顿图.哈密顿图就是从一点出发,经过所有的必须且只能一次,最终回到起点的路径.图中有的边可以不经过,但是不会有边被经过两次. 与欧拉图的区别:欧拉图讨论的实际上是图上关于边的可行便利问题,而哈密顿图的要求与点有关. 判定: 一:Dirac定理(充分条件) 设一个无向图中有N个顶点,若所有顶点的度数大于等于N/2,则哈密顿回路一定存在.(N/2指的是⌈N/2⌉,向上取整) 二:基本的必要

欧拉图和哈密顿图

欧拉图和哈密顿图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 通路和回路 给定图G<V,E>中结点和边相继交错出现的序列,其中V表示图中结点集合,E表示图中边的集合 \[\Gamma=v_0e_1v_1e_2v_2...e_kv_k\] 若\(\Gamma\)中边\(e_i\)的两个端点是\(v_{i-1}\)和\(v_i\) (==G是有向图时要求\(v_{i-1}与v_{i}分别是e_{i}的起始点和终点\)==),i=1,2,3,...k,则称\(\Gamma为结点v_0到结

程序运行状态的判定

怎么知道手机的一个程序是否在运行,又或是在不在前台运行呢?下面一个方法就可以判定了. /** * 返回app运行状态 * 1:程序在前台运行 * 2:程序在后台运行 * 3:程序未启动 * 注意:需要配置权限<uses-permission android:name="android.permission.GET_TASKS" /> */ public int getAppSatus(Context context, String pageName) { ActivityM

POJ C程序设计进阶 编程题#3:运算符判定

编程题#3:运算符判定 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 两个整数 a 和 b 运算后得到结果 c.表示为:a ? b = c,其中,?可能是加法 +,减法 -,乘法 *,整除 / 或 取余 %.请根据输入的 a,b,c 的值,确定运算符.如果某种运算成立,则输出相应的运算符,如果任何运算都不成立,则输出 error. 例如: 输入: 3,4,5 输出: er

混合图的欧拉回路判定

对于有向图和无向图的欧拉回路判定,很容易做到.那对于混合图呢?? 混合图就是图中既存在无向边又存在有向边的图. 至于解法: 转载自这里 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路.因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路. 好了,现在每个点入度和出度之差均为偶数.那么将这个偶数除以2,得x.也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出 = 入.如果

NEFU120 梅森素数【Lucas-Lehmer判定】

题目链接: http://acm.nefu.edu.cn/JudgeOnline/problemshow.php?problem_id=120 题目大意: 给一个数p,若Mp = 2^p - 1是梅森素数,则输出"yes",否则输出"no". 思路: 这道题p小于62.Mp就小于2^62-1.如果直接进行素数判别会比较慢,用筛法的话数据量 又会很大.所以这里用了Lucas-Lehmer判定法则. Lucas-Lehmer判定法则具体步骤: 如果要判定的整数位Mp =

Java虚拟机:如何判定哪些对象可回收?

版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 在堆内存中存放着Java程序中几乎所有的对象实例,堆内存的容量是有限的,Java虚拟机会对堆内存进行管理,回收已经"死去"的对象(即不可能再被任何途径使用的对象),释放内存.垃圾收集器在对堆内存进行回收前,首先要做的第一件事就是确定这些对象中哪些还存活着,哪些已经死去.Java虚拟机是如何判断对象是否可以被回收的呢? 引用计数算法        引用计数算法的原理是这样的:给对象添加一个引用计数器,每当有一个地方引用它时,计