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

来源:互联网 发布:域名怎么备案 编辑:程序博客网 时间:2024/05/02 16:14
/*  函数功能:求解哈密顿环(无向图,有向图请自改)问题,输出全部不相同的环,即经过图中每个结点并且只经过一次的可行解。  *  作者    :王宇虹  *  时间    :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";}elseHamiltonian(k+1,x);         //深度优先进入下一层 }while(1);}void Hamiltonian(int *x){Hamiltonian(1, x);}
0 0