哈密尔顿回路问题

/*******************************************************/
/*                  哈密尔顿回路问题                   */
/*从一个顶点出发,经过每个顶点恰好一次,然后回到出发点 */
/*******************************************************/

#include<iostream>
#define N 15  //最多顶点数
using namespace std;

int main(){
	/*函数声明*/
	void creat_c(int B[],bool c[][N], int n);
	void show_x(int x[], int n);
	void hamilton(int count,int n,int x[],bool c[][N]);

	int n;  //顶点个数n
	cout << "请输入图的顶点个数(不超过15):";
	cin >> n ;

	int B[N] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//各顶点编号
	bool(*c)[N] = new bool[N][N];  //图的邻接关系
	cout << "\n请输入图<i,j>顶点若有边,则输1,否则输0:\n";
	creat_c(B,c,n);   //输入图的邻接关系

	int count = 0;    //解个数赋初值0
	int * x = new int[N]; //定义解向量
	cout << "哈密尔顿回路问题的解向量分别为:\n";
	hamilton(count,n,x,c); /*回溯法求解哈密尔顿算法*/

	system("pause");
	return 0;
}

/*输入图的邻接关系*/
void creat_c(int B[],bool c[][N], int n){
	for (int i = 0; i <n; i++){
		for (int j =0; j <i; j++){
			if (i == j){  //自身到自身,无关系
				c[i][j] = false;
				continue;
			}
			cout << "边<" << B[i] << "," << B[j] << ">: ";
			cin >>c[i][j];
			c[j][i] = c[i][j];  //无向图,邻接关系对称
		}
	}
	cout << endl;
}

/*打印解向量*/
void show_x(int x[], int n){
	cout << x[0]+1;
	for (int i = 1; i <n; i++)
		cout << "->" << x[i]+1;
	cout << endl;
}

/*回溯法求解哈密尔顿算法*/
void hamilton(int count,int n,int x[],bool c[][N]){
	bool * s = new bool[N];
	for(int i=0;i<n;i++){  //初始化
		x[i]=0;
		s[i]=false;
	}
	int k=1;s[0]=true;x[0]=0;

	while(k>=1){
		x[k]=x[k]+1;  //搜索下一个顶点编号
		while(x[k]<n){
			if(!s[x[k]]&&c[x[k-1]][x[k]])
				break;  //搜索到一个顶点
			else
				x[k]=x[k]+1;  //否则搜索下一个顶点编号
		}
		if((x[k]<n)&&(k!=n-1)){  //搜索成功且k<=n-1
			s[x[k]]=true; k++;   //向前推进一个顶点
		}
		else if((x[k]<n)&&(k==n-1)&&c[x[k]][x[0]]){
			show_x(x, n); count++;  //是最后的顶点,打印结果,记录解个数
		}
		else{
			x[k]=0;k--;s[x[k]]=false;  //搜索失败,回溯到前一个顶点
		}
	}
	delete []s;
	cout << "共有" << count << "个解!\n\n";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值