#include <iostream>
#define MAXSIZE 30 /*结点数小于30 */
#define ALWAYS 1 /*这是一个NP完全性问题*/
#define SUCCESS 1 /*所以结点不能过多,否则等很久*/
#define FAILURE 0
#define YES 1
#define NO 0
using namespace std;
void read_in(float connected[][MAXSIZE], int *n)
{
int i, j;
float temp;
cout<<"input N"<<endl;
cin>>*n; /* 输入顶点数*/
for (i = 0; i < *n; i++)/* 初始入临接矩阵*/
{
for (j = 0; j < *n; j++)
{
connected[i][j] = 0.0;
}
}
cout<<"input start_vex end_vex path_length"<<endl;
cout<<"input 0 0 0 end "<<endl;
cin>>i>>j>>temp; /*输入第一条边 */
while (i != 0 && j != 0)
{ /* end ? */
connected[i-1][j-1] = temp; /* 给边付值 */
connected[j-1][i-1] = temp; /* */
cout<<"input start_vex end_vex path_length"<<endl;
cin>>i>>j>>temp; /* 输入下一条边 */
}
for (i = 0; i < *n; i++) /* 对角线付0 */
{
connected[i][i] = 0.0;
}
}
void display(int cycle[], int n)
{
int i;
cout<<endl<<endl<<"A Hamilton Cycle is Listed as Follows :"<<endl;
cout<<endl<<cycle[0]+1;
for (i = 1; i < n; i++)
{
cout<<"->"<< cycle[i]+1;
}
cout<<"->"<<cycle[0]+1;
}
int hamilton(float connected[][MAXSIZE], int cycle[], int n, int start)
{
int *visited; /* 保存访问过的结点 */
int top, i,j,min_path[MAXSIZE],flag=0;
float temp,old_temp=10000000;
visited = (int *) malloc(sizeof(int)*n); /* 为保存结点分配空间 */
for (i = 0; i < n; i++) /* 初始入访问结点 */
{
visited[i] = NO;
}
visited[start] = YES; /* 保存第一个访问结点*/
cycle[0] = start; /* 栈底放入第第一个结点 */
cycle[1] = 0; /* */
top = 1; /* 栈顶为1 */
while (ALWAYS)
{
for (i = cycle[top]; i < n; i++) /*循环找出下个结点 */
{
if (connected[cycle[top-1]][i] && !visited[i]) break;
}
if (i < n)
{ /* 如果找到了下一个要访问的结点 */
cycle[top] = i;/* 结点压栈*/
visited[cycle[top]] = YES;
if (top == n-1 && connected[cycle[top]][start])/*如果己经访问了N个结点,而且最后一个结点和初始结点有边相连*/
{ /*则找到一条哈密尔顿图*/
temp=0;
flag=1;
for(j=0;j<top;j++)/*求出这条哈密尔顿图的路程*/
{
temp+=connected[cycle[j]][cycle[j+1]];
}
temp+=connected[cycle[top]][start];
if(temp<old_temp)/*如果路程小于上一条路路程, 则保存这条路径*/
{
for(j=0;j<n;j++)
{
min_path[j]=cycle[j];
}
old_temp=temp;
}
display(cycle,n);/*显示这条路径*/
visited[cycle[top]]=NO;/*把当前顶点设为没访问过*/
visited[cycle[--top]] = NO;/*退出当前顶点*/
if (top == 0)/*如果开始结点都要加,则说明己经不在有路径了*/
{
if(flag)
{
cout<<endl<<endl<<"Min length path= "<<old_temp;
display(min_path,n);
}
free(visited); /* YES, failed. */
return FAILURE;
}
cycle[top]++;/*回蒴上个的下一个结点*/
}
else
{/* otherwise, advance. */
cycle[++top] = 0;
}
}
else
{ /* 如果没有找到 */
visited[cycle[--top]] = NO; /* 回蒴 */
if (top == 0)
{
if(flag)/*显示己找到的路径*/
{
cout<<endl<<endl<<"Min length path "<<old_temp;
display(min_path,n);
}
free(visited);
return FAILURE;
}
cycle[top]++; /* 移到下一个 */
}
}
}
void main(void)
{
float connected[MAXSIZE][MAXSIZE];
int cycle[MAXSIZE];
int n,start;
cout<<"Hamilton Cycle Program"<<endl;
cout<<"======================"<<endl;
cout<<"Input start vex"<<endl;
cin>>start;/*输入初始结点*/
read_in(connected, &n);
hamilton(connected, cycle, n, start-1);
cin>>n;
}