回溯法求解哈密顿回路问题
2013-08-21 14:52 youxin 阅读(5942) 评论(0) 编辑 收藏 举报假设图中有n个顶点1,2,3,4,5,6,7
用x[i] 存储问题的解。
x[1]存储初始点,x[2]存储第二个点。以此类推。
bool b[n+1][n+1] 存储图的邻接矩阵。
约束条件:
xi!=xj 0<=i,j<=n i不等于j
b[xi-1][xi]=true 当前点与前一个点邻接
特别地,当i=n时还要满足b[1][n]=true;
代码:
#include <iostream> #include<cstdio> using namespace std; bool b[100][100]; //图的邻接矩阵 bool check(int x[],int n, int k) { for(int i=1;i<k;i++) { if(x[i]==x[k] ) return false; } int tmp1,tmp2; tmp1=x[k-1],tmp2=x[k]; if(b[tmp1][tmp2]) //if(b[k-1][k])错误 { if(k==n) return b[1][tmp2]; //k等于n要单独考虑 return true; } else return false; } void hamilton(int x[],int n,int k) { for(int i=1;i<=n;i++) { x[k]=i; if(check(x,n,k)) { if(k==n) { for(int m=1;m<=n;m++) cout<<x[m]<<ends; cout<<endl; } else { hamilton(x,n,k+1); } } } } void hamilton2(int x[],int n) { x[2]=0; int k=2; while(k>1) { x[k]+=1; while(x[k]<=n && !check(x,n,k) ) { x[k]+=1; } if(x[k]<=n) { if(k==n) { for(int m=1;m<=n;m++) cout<<x[m]<<ends; cout<<endl; x[k]=0; k--; } else { k++; x[k]=0; } } else { x[k]=0; k--; } } } int main() { freopen("hamilton.txt","r",stdin); int n; cout<<"输入顶点数"<<endl; cin>>n; int *x=new int[n+1]; int edges; cout<<"边数"<<endl; cin>>edges; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) b[i][j]=true; else b[i][j]=false; } int start,end; cout<<"属于边d的起点和终点"<<endl; for(int i=1;i<=edges;i++) { cin>>start>>end; b[start][end]=true; b[end][start]=true; } x[1]=1; //hamilton(x,n,2); hamilton2(x,n); }
用递归和不用递归结果都一样。
注意划红线 部分;
int k=2; while(k>1)
为什么k>1。
第一个点x[1]=1;已经确认了,我们从第二个点开始。
这跟k=1; k>0是一样的道理。
输入:
5
8
1 2
1 4
2 4
2 3
4 5
3 5
3 4
2 5
输出:
上面代码中的第一个点默认x[1]=1;就是说我们已经规定了起点,如果我们不规定起点,找出所有的哈密顿回路,怎么办?
调用之前不用写x[1]=1。
把:
x[2]=0; int k=2; while(k>1) { x[k]+=1;
改为
x[1]=0; int k=1; while(k>0) { x[k]+=1;
就可以了吗?不可以,运行就报错。
原因是什么,是我们的check函数:
bool check2(int x[],int n, int k) { for(int i=1;i<k;i++) { if(x[i]==x[k] ) return false; } int tmp1,tmp2; tmp1=x[k-1],tmp2=x[k]; if(b[tmp1][tmp2]) //if(b[k-1][k])错误 {
当k=1时x[0]是一个随机的数,我们没有赋值。这样b[tmp1][tmp2]必然有问题,我们只要加上k是否为1的判断就可以了。
在函数最前面加上;
if(k==1) return true;、
就可以。
输出;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2012-08-21 css position
2012-08-21 little box:three column
2012-08-21 little box: two box
2012-08-21 eric书:text属性
2012-08-21 eric书:css继承
2012-08-21 转:Quirks模式与Standards模式
2012-08-21 外边距折叠