无向图经过所有的节点一次且仅一次:哈密瓜路径

无向图经过所有的边一次且仅一次:欧拉路径

带权哈密顿路径就是旅行商问题。

参考博客:https://blog.csdn.net/zhouzi2018/article/details/81278942

过程:

1:任意找两个相邻的节点S和T,在其基础上扩展出一条尽量长的没有重复结点的路径.即如果S与结点v相邻,而且v不在路径S -> T上,则可以把该路径变成v -> S -> T,然后v成为新的S.从S和T分别向两头扩展,直到无法继续扩展为止,即所有与S或T相邻的节点都在路径S -> T上.

2:若S与T相邻,则路径S -> T形成了一个回路.

3:若S与T不相邻,可以构造出来一个回路.设路径S -> T上有k+2个节点,依次为S, v1, v2, ..., vk, T.可以证明存在节点vi(i属于[1, k]),满足vi与T相邻,且vi+1与S相邻.找到这个节点vi,把原路径变成S -> vi -> T -> vi+1 ,即形成了一个回路.

4:到此为止,已经构造出来了一个没有重复节点的的回路,如果其长度为N,则哈密顿回路就找到了.如果回路的长度小于N,由于整个图是连通的,所以在该回路上,一定存在一点与回路之外的点相邻.那么从该点处把回路断开,就变回了一条路径,同时还可以将与之相邻的点加入路径.再按照步骤1的方法尽量扩展路径,则一定有新的节点被加进来.接着回到路径2.

证明:

跟据鸽巢定理,既然与S和T相邻的点都在路径上,它们分布的范围只有v1,v2---,vk这k个点,k<=N-2,跟据哈密顿回路的第一个判断条件,d(S)+d(T)>=N,那么v1,v2,---vk这k个点中一定有至少2个点同时与S和T相连,根据鸽巢定理,肯定存在一个与S相邻的点vi和一个与T相邻的点vj,满足j=i+1

伪代码:

设s为哈密顿回路的起始点,t为哈密顿回路中终点s之前的点.ans[]为最终的哈密顿回路.倒置的意思指的是将数组对应的区间中数字的排列顺序反向.

1:初始化,令s = 1,t为s的任意一个邻接点.

2:如果ans[]中元素的个数小于n,则从t开始向外扩展,如果有可扩展点v,放入ans[]的尾部,并且t=v,并继续扩展,如无法扩展进入步骤3.

3:将当前得到的ans[]倒置,s和t互换,从t开始向外扩展,如果有可扩展点v,放入ans[]尾部,并且t=v,并继续扩展.如无法扩展进入步骤4.

4:如果当前s和t相邻,进入步骤5.否则,遍历ans[],寻找点ans[i],使得ans[i]与t相连并且ans[i +1]与s相连,将从ans[i + 1]到t部分的ans[]倒置,t=ans[i +1],进如步骤5.

5:如果当前ans[]中元素的个数等于n,算法结束,ans[]中保存了哈密顿回路(可看情况是否加入点s).否则,如果s与t连通,但是ans[]中的元素的个数小于n,则遍历ans[],寻找点ans[i],使得ans[i]与ans[]外的一点(j)相连,则令s=ans[i - 1],t = j,将ans[]中s到ans[i - 1]部分的ans[]倒置,将ans[]中的ans[i]到t的部分倒置,将点j加入到ans[]的尾部,转步骤2.

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;const int maxn=410;
int ans[maxn];
int visit[maxn];// in case of reoccurrence
int friendt[maxn][maxn];
int n,m;
int s,t;
int num;void rever(int s,int t){while(s<t){int tmp=ans[s];ans[s]=ans[t];ans[t]=tmp;s++;t--;}
}void hamilton()
{s=1;for(int i=1;i<=n;i++){if(friendt[s][i]){t=i;break;}}ans[0]=s;ans[1]=t;num=2;//cout<<s<<" "<<t<<endl;memset(visit,0,sizeof(visit));visit[s]=1;visit[t]=1;int v;while(1){while(1){v=0;for(int i=1;i<=n;i++){if(friendt[t][i]&&!visit[i]){v=i;break;}}if(v){ans[num++]=v;t = v;visit[v]=1;}else break;}//cout<<t<<endl;rever(0,num-1);int tmp=s;s=t;t=tmp;while(1){v=0;for(int i=1;i<=n;i++){if(friendt[t][i]&&!visit[i]){v=i;break;}}if(v){ans[num++]=v;t = v;visit[v]=1;}else break;}if(!friendt[s][t]){for(int i=1;i<num-2;i++){if(friendt[ans[i]][t]&&friendt[ans[i+1]][s]){rever(i+1,num-1);t=ans[i+1];break;}}}if(num==n)return;int ind,j;for(int i=1;i<=n;i++){if(!visit[i]){j=i;break;}}for(int k=1;k<num-2;k++){if(friendt[ans[k]][j]){ind=k;break;}}s=ans[ind-1];t=j;rever(0,ind-1);rever(ind,num-1);ans[num++]=j;visit[j]=1;}
}int main()
{//freopen("in.txt","r",stdin);while(cin>>n>>m&&(n||m)){n = 2*n;//cout<<n<<endl;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){if(j==i)friendt[i][j]=0;else friendt[i][j]=1;}for(int i=0;i<m;i++){int a,b;scanf("%d%d",&a,&b);friendt[a][b]=0;friendt[b][a]=0;}num=0;hamilton();for(int i=0;i<n;i++)printf("%d ",ans[i]);cout<<endl;}return 0;
}

POJ-2438 哈密顿环 哈密瓜很甜相关推荐

  1. 计算机专业男生好撩吗,撩男生很甜很撩的句子 一撩一个准

    撩男生很甜很撩的句子 一撩一个准 软件 linshaomin 2019-01-31 16:36 佚名 2019-01-31 16:36:46 微信朋友圈说说 除了我你别无选择!因为再也没有人会比我更爱 ...

  2. 算法 {哈密顿路径,哈密顿环}

    算法 {哈密顿路径,哈密顿环} @LOC_COUNTER = 2; 哈密顿路径,哈密顿环 定义 哈密顿路径; 对于一个有N个点的图(有向无向均可), 如果一条路径 经过了图中所有点1,2,...,N ...

  3. 橘子很甜,月亮很圆 --- 记一次同仁医院半飞秒+角膜交联手术

    选择医院 网上查资料,在北京最牛的眼科医院就是同仁医院了 医院地址:北京市东城区东交民巷1号 选择医生 查资料我了解到,虽然是仪器来主导手术,但是手术切削的参数.制定的方案以及手术过程中的人为操作都需 ...

  4. 怎样用计算机来撩人,超甜撩人套路一问一答 很甜很撩的句子撩男生

    1.;你真很讨厌耶 ;怎么了? ;你凭啥驻扎在我心里,赶也赶不走? 2.;突然觉得自己很自私. ;? ;我只爱你,没给任何女生机会来追我. 3.;姑娘,小生想向你问路. ;公子,想去哪里? ;我想去你 ...

  5. poj 2392 dp 不是很懂哎!!!Space Elevator

    大意:有K种block去建塔,每种每个都有一个高度H,用了当前的block塔的高度不能超出a,和每种的数量.求塔最高能建多高. 分析:这题就是一个多重背包,但有一点变动,必须先以a从小到大排序,因为如 ...

  6. POJ 2152 树型DP //很棒的题

    题意:Z国有n个城市,从1到n给这些城市编号.城市之间连着高速公路,并且每两个城市之间有且只有一条通路.不同的高速公路可能有不同的长度.最近Z国经常发生火灾,所以当地政府决定在某些城市修建一些消防站. ...

  7. 最短哈密顿环 退火_hdu 5418 Victor and World (最短哈密顿回路)

    给你n个国家,m条路线:u_i与v_i之间的距离w_i. 输出从1号国家出发经过每个国家至少一次再回到1号国家的最短距离. [官方题解]: 我们首先需要预处理出任意两个国家之间的最短距离,因为数据范围 ...

  8. hdu 4337——poj 2438(哈密尔顿回路求解模板)

    转:http://imlazy.ycool.com/post.2072698.html Dirac 定理:设一个无向图中有 N 个节点,若所有节点的度数都大于等于 N/2,则汉密尔顿回路一定存在.注意 ...

  9. 用php语言说句情话,追女孩表白情话短句大全2018 对女朋友说的很甜暖心的话句子...

    男生在追求女生的时候,怎么可以少了甜言蜜语的话呢?以下追女孩子的甜言蜜语短句送给你,希望你能将这份情传递到她的心中. 相关推荐>>关于追女生的心情说说短语大全2018 说给女孩的浪漫句子语 ...

最新文章

  1. 头条hr就是刚:拒绝Offer或者放弃入职等于永远跟头条没关系!
  2. vue-router2路由参数注意问题
  3. matlab 工具箱application compiler的作用_matlab机器人工具箱下载与使用
  4. red hat安装宝塔_如何在几分钟内安装Red Hat Container Development Kit(CDK)
  5. py脚本:linux系统下定时清理文件
  6. python xposed_xposed + python 怎么爬取微信朋友圈的数据
  7. 双十一,不玩盖楼,直接大额降价!
  8. Qt UDP Socket丢包问题(实现百兆级速率无丢包)
  9. 微信小程序中使用自定义图标(阿里icon)的方法
  10. docker编配和服务发现
  11. 4个漂亮的wordpress企业主题
  12. java exe 程序
  13. 武则天用无字碑深切蔑视男人
  14. 《机器学习实战:基于Scikit-Learn、Keras和TensorFlow(第2版)》学习笔记
  15. 运营商大数据丨电销行业如何高效获得精准客户
  16. excel拆分数据为多个工作表
  17. springboot项目接入天猫精灵
  18. 新“病毒营销”案例--凡客体
  19. b 标签和 strong 标签,i 标签和 em 标签的区别?
  20. softether 穿越防火墙原理

热门文章

  1. 57 张 PPT 揭开机器学习本质
  2. Mysql批量导出与批量导入
  3. 2020最全的BAT大厂面试题整理改版
  4. python作品-python+作品
  5. CountDownTimer倒计时器的使用
  6. linux parted软件包,为Everest Linux构建QtParted的rpm包(一)
  7. Linux驱动开发(十八)---网络(网卡)驱动学习
  8. 中国联通3G网络覆盖全国200余城市
  9. IBM服务器装系统看不到硬盘,IBM SATA硬盘的笔记本安装系统找不到硬盘解决方案...
  10. 计算机专业只喜欢玩游戏,为什么有人只喜欢打人机?和电脑打有什么意思啊,今天终于想通了...