Hamilton回路

#include <bits/stdc++.h>
#define INF -1

/*全局变量*/
int n,						//结点数目
    start=1,                  //路径起始节点
	length = 0,				//临时存储当前路径的路径长
	shortest_length = INF,  //存储最短路径长
	**graph,				//存储图
	*path,				    //临时存储路径
	*best_path;			    //存储最短路径

/*交换*/
void swap(int *array, int i, int j)
{
	int temp;
	temp = array[i];
	array[i] = array[j];
	array[j] = temp;
}

/*结果输出*/
void output()
{
	printf("最短路径长度是%d\n", shortest_length);
	printf("此时路径为:%d", best_path[1]);
	for (int i = 2; i < n + 1; i++)
		printf("-->%d", best_path[i]);
	printf("-->%d\n", best_path[1]);
}

/*递归回溯*/
void travel(int t)
{
	/*终止条件,并处理最后一层*/
	if (t == n)
	{
		if (graph[path[t - 1]][path[t]] != INF
			&& graph[path[t]][1] != INF
			&& (length + graph[path[t - 1]][path[t]] + graph[path[t]][1] < shortest_length || shortest_length == INF))
		{
			/*更新路径和最短回路的长度*/
			for (int i = 0; i < n + 1; i++)
				best_path[i] = path[i];
			shortest_length = length + graph[path[t - 1]][path[t]] + graph[path[t]][1];
		}

		return;
	}

	/*递归的主体部分*/
	for (int i = t; i < n + 1; i++)
	{
		if (graph[path[t - 1]][path[i]] != INF    /*判断是否有路*/
			&& (length + graph[path[t - 1]][path[i]] < shortest_length || shortest_length == INF)) /*判断是否比当前最短路径还要长,如果还没形成回路就已经比shortest_length大就直接进入下一轮*/
		{
			/*通过交换调整最短路径*/
			swap(path, i, t);
			/*更新length的值,便于下一层递归的筛选*/
			length += graph[path[t - 1]][path[t]];
			/*进入下一层递归;*/
			travel(t + 1);
			/*还原*/
			length -= graph[path[t - 1]][path[t]];
			swap(path, i, t);
		}
	}
}

int main()
{
	printf("请输入节点数与边数:");
	scanf("%d",&n);
	/*内存分配*/
	graph = (int**)malloc(sizeof(int*) * (n + 1));//为二维数组分配n+1行
	for (int i = 0; i <= n; i++)
		graph[i] = (int*)malloc(sizeof(int) * (n + 1));

	path = (int*)malloc(sizeof(int)*(n + 1));

	best_path = (int*)malloc(sizeof(int)*(n + 1));

	/*初始化*/
	for (int i = 0; i < n + 1; i++)
	{
		path[i] = i;

		for (int j = 0; j < n + 1; j++)
			graph[i][j] = INF;
	}

	/*图输入,可以根据需要自行修改,结点从1开始编号,且编号即下标*/
	int s,w,u,v;
	scanf("%d",&s);
	printf("请输入邻接矩阵:");
	for (int i = 1; i <= s; i++)
	{
		scanf("%d%d%d",&u,&v,&w);
		graph[u][v]=graph[v][u]=w;
	}
	

	/*调用递归开始遍历路径*/
	travel(start+1);

	/*结果输出*/
	output();

	/*释放动态开辟的空间*/
	for (int i = 0; i < n + 1; i++)
		free(graph[i]);
	free(graph);
	free(best_path);
	free(path);

	return 0;
}
/*
8
20
1 2 54
1 3 26
1 4 42
1 8 51
2 5 51
2 6 44
2 7 42
2 8 49
2 3 34
3 5 45
3 6 52
3 7 34
3 8 59
4 5 89
4 6 54
4 8 50
5 6 43
6 7 43
6 8 47
7 8 16
*/

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值