哈密顿回路-相异数字序列问题
来源:互联网 发布:微店和淘宝 编辑:程序博客网 时间:2024/04/27 18:51
要满足两个条件:
1.封闭的环
2.是一个连通图,且图中任意两点可达
经过图(有向图或无向图)中所有顶点一次且仅一次的通路称为哈密顿通路。
经过图中所有顶点一次且仅一次的回路称为哈密顿回路。
具有哈密顿回路的图称为哈密顿图,具有哈密顿通路但不具有哈密顿回路的图称为半哈密顿图。
平凡图是哈密顿图。
问题描述
给你一个整数m,找出这样一个长为2^m的0,1序列,使得依次取长为m的串时,得到的2^m个长为m的0,1串,它们表示了互不相同的十进制数。
输入:第一行是一个整数n,表示需考察n个整数(1<=n<=15),接着n行,每行有一个整数m(1<=m<=15)
样例:
2
2
3
m=2: 0011
m=3: 00010111
考察m=2的情形,长为2的序列00开始,每个序列后面接0或1,于是接0得000,前面两位00和后面两位的00相同,应排除本次接0的情况,应接1,变成001,后01与前00不同,应保留填上1.确定01后,对01后面接0或1,应该有010和011,都可行,取低2位10或11,类似接0或1.最后得出下面有向图。
#include <iostream>using namespace std;#define MAXN 65535struct node { int left, right; // left,right分别记录当前节点通过添0,添1而得的序列 int visited; // 标记是否被访问到,-1表示未访问过,0表示左支,1表示右支};typedef node NODE;NODE p[MAXN]; // 表示节点数组long maxb, a[MAXN]; // a存放最优解int m;void init(int m) // 初始化构建一个有向图{ long i, k; maxb = (1<<m) - 1; // 记有向图的顶点最大顶点数-1 for (i = 0; i <= maxb; i++) { // 设定无左右儿子,无访问值 p[i].left = -1; p[i].right = -1; p[i].visited = -1; k = i; // 考察当前十进制数是i的节点的左右儿子生成情况 k = (k << 1) & maxb; // 节点的二进制数尾添0,用位操作,取后m位 if (k != i) { p[i].left = k; // 去左支重复节点 } k = k + 1; // 尝试右支 if (k != i) { p[i].right = k; // 去右支重复节点 } }}// 判断数b与当前部分解a前k个是否有相同的bool NotEqual(int k, int b){ bool flag = true; int i; for (i = 0; i <= k; i++) { if (a[i] == b) { flag = false; break; } } return flag;}// 求最优解a,采用迭代回溯算法void Compt(){ long i = 1, j; bool flag = false; a[0] = 0; p[0].visited = 0; while (true) // 搜索子树 { while (i <= maxb && p[a[i-1]].left != -1 && p[a[i-1]].left != 0 && NotEqual(i-1, p[a[i-1]].left)) {// 如左子树一直可行,沿左子树一直下去 a[i] = p[a[i-1]].left; //取左儿子值 p[a[i-1]].visited = 0; //设访问左儿子标志 i++; flag = false; // 设定可能进入右子树标志 } // 如果个数已经够了,直接输出结果 if (i > maxb) { for (j = 0; j <= maxb; j++) { cout << ((a[j]&(1<<(m-1)))>>(m-1)); // 按字符串输出 } cout << endl; return; } else // 如果个数未满足要求 { // 若右子树可行进入右子树 if (p[a[i-1]].right != -1 && p[a[i-1]].right != 0 && NotEqual(i-1, p[a[i-1]].right)) { a[i] = p[a[i-1]].right; //取右儿子值 p[a[i-1]].visited = 0; //设访问右儿子标志 i++; flag = false; // 设定可能进入左子树标志 } } while (!flag) // 剪枝回溯 { i--; while (i > 0 && p[a[i-1]].visited == 1) // 沿右子树返回 { a[i] = -1; p[a[i-1]].visited = -1; // 取消访问标志 i--; } if (p[a[i-1]].right != -1 && p[a[i-1]].right != 0 && NotEqual(i-1, p[a[i-1]].right)) { a[i] = p[a[i-1]].right; //取右儿子值 p[a[i-1]].visited = 1; //设访问右儿子标志 i++; flag = true; // 设定可能进入左子树标志 } } }}int main(){ int i, n; cin >> n; for (i = 0; i < n; i++) { cin >> m; cout << "m=" << m << ":" << endl; if (m <= 0) { cout << "Impossible!" << endl; } else { init(m); Compt(); } } system("pause"); return 0;}
- 哈密顿回路-相异数字序列问题
- 回溯——哈密顿回路问题
- 最小哈密顿回路
- 哈密顿回路
- poj3229 哈密顿回路
- poj3311 哈密顿回路
- 哈密顿回路模版
- Hamilton-哈密顿回路
- 哈密顿回路
- 哈密顿回路
- HDU 2181 哈密顿绕行世界问题 (求一个图的所有哈密顿回路)
- POJ2438-求解哈密顿回路
- poj 2438哈密顿回路
- HDU4337(哈密顿回路)
- 哈密顿回路及解法
- 欧拉回路及哈密顿回路
- 哈密顿路问题
- 哈密顿路问题
- 走技术线,还是技术管理线?
- (40)21.4.1 装饰性花园---Java编程思想之并发笔记
- 软件技术发展的驱动力
- 再见,2012
- (41)21.4.1 并发 练习 17---Java编程思想之并发笔记
- 哈密顿回路-相异数字序列问题
- Flex HTTPService 读取XML并显示在 Tree 中
- (42)21.4.2 在阻塞时终结---Java编程思想之并发笔记
- 从数据访问程序看设计模式之工厂模式、抽象工厂模式
- Html:frameset 使用心得
- (43)21.4.3 中断---Java编程思想之并发笔记
- (44)21.4.3 并发 练习 18---Java编程思想之并发笔记
- (45)21.4.3 并发 练习 19---Java编程思想之并发笔记
- (46)21.4.3 并发 练习 20---Java编程思想之并发笔记