哈密顿环求解 C++实现 回溯法

/*  函数功能:求解哈密顿环(无向图,有向图请自改)问题,输出全部不相同的环,即经过图中每个结点并且只经过一次的可行解。 
 *  作者    :王宇虹 
 *  时间    :2015年5月21日  13:23:00.000
 *  编译环境:Dev-C++ 5.8.3
 */
#include<iostream>
#include<cstring>
using namespace std;
int n,m,g,i;  //n表示无向图中结点个数,g表示结点关系个数 
int a[10000][10000];  //只开到结点个数为10000的范围
void NextValue(int k,int* x); 
void Hamiltonian(int k,int *x);
void Hamiltonian(int *x);

int main()      //主函数
{
	memset(a,0,sizeof(a)); 
	cout << "请输入无向图中结点的个数: ";
	cin >> n;
	cout << "请输入边的条数: ";
	cin >> g;
	int *x = new int[10000];
    int u, v;
    for(i = 0; i < n; i++) x[i] = 0;
    for(i = 0; i < g; i++)
	{
		cout << "请输入边:";
		cin >> u >> v;
	    a[u][v] = a[v][u] = 1;
	}
	cout << "可行解: " << endl; 
	Hamiltonian(x);

    return 0;
}

void NextValue(int k,int* x)
{
	int j;
    do{
		x[k] = (x[k]+1) % n;    		 	//下一个结点编号 
		if(!x[k]) return;         		 
		    if(a[x[k-1]][x[k]]){              //(x[k-1],x[k])是否是图中一条边 
		    for(j = 0; j < k; j++)      //检查与前k个节点是否相同
		        if(x[j] == x[k])	break;  //结点x[k]与前k个结点有重复 
		    if(j == k)                      //x[k]是当前可取的结点编号 
		        if((k < n-1)||(k == n-1) && a[x[n-1]][x[0]])
			      return;
			}
	}while(1);
}
void Hamiltonian(int k,int *x)
{
	do{
		NextValue(k, x);             //产生x[k]的下一个值 
		if(!x[k])  return;               //x[k]=0表示x[k]已经没有可取值 
		if(k == n - 1) {                //输出一个哈密顿环 
			for(int i = 0; i < n; i++)  cout<<x[i]<<' ';
			cout<< "0\n";
		}
		else
			Hamiltonian(k+1,x);         //深度优先进入下一层 
	}while(1);
}
void Hamiltonian(int *x)
{
	Hamiltonian(1, x);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-05-21 14:38  Tob__yuhong  阅读(110)  评论(0编辑  收藏  举报

导航