蛮力法(04图问题)哈密顿回路和TSP问题

====================================================================================================================================================
哈密顿回路: 从一个城市出发,经过每一个城市恰好一次,然后回到出发城市。
求解: 对于给定的无向图,就是考察图中所有顶点的全排列
满足: ①相邻顶点之间存在边,②最后一个顶点和第一个顶点之间存在边
时间复杂度: O(n!)

代码:

//采用dfs,并且适当减枝。 下面我们采用这种方法求解
//哈密顿回路问题
#include<stdio.h>
#include<windows.h>
int x[100];
int visit[100];
int arc[6][6];
int n;


void  dfs(int step)
{
	int i,j;
	if(step==n&&arc[x[step-1]][0]==1) //最后一步到达的顶点与起点之间存在路径 
	{
		printf("路径:");
		for(i=0;i<n;i++)
			printf("%d ",x[i]+1);
		printf("\n");
			return ;
			
	}
	else
	{
		for(j=0;j<n;j++)
		{
			if(visit[j]==0&&arc[x[step-1]][j]==1) //j未访问并且当前顶点与j顶点之间存在路径 
			{
				visit[j]=1;
				x[step]=j;	//下一个访问的顶点为j 
				dfs(step+1);
				visit[j]=0;
				x[step]=0;			
			}
			
		}
	}
	
} 
int main(void)
{
	int i,j;
	scanf("%d",&n);
 	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			scanf("%d",&arc[i][j]);
	visit[0]=1;  //起点置为已经访问
	x[0]=0;
	dfs(1);
	Sleep(10000);
	return 0;
	
}

结果示例:
在这里插入图片描述

====================================================================================================================================================
TSP问题
旅行商问题与哈密顿回路问题十分相似,都是经过每一个顶点一次最后回到出发的城市,不同的是旅行商问题对应的是完全图,即每个顶点之间都存在路径,并且路径长度已知。

代码:

//旅行商问题,对应完全图
//哈密顿回路问题 对应非完全图 
#include<stdio.h>
int x[100];
int visit[100];
int arc[6][6];
int n,count,bestCount=9999999;
void dfs(int step,int count)
{
	int i,j;	 
	if(bestCount<count) //减枝,当然所经过的路径长度大于最小长度 
		return;
	if(step==n) //已经走过n个顶点 
	{
	 
		count+=arc[x[step-1]][0];
		bestCount=count;	 
		return ;
			
	}
	else
	{
		for(j=0;j<n;j++)
		{
			if(visit[j]==0) //j未访问
			{
				visit[j]=1;//置为已经访问 
				x[step]=j;	//访问该顶点 
				dfs(step+1,count+arc[x[step-1]][j]); 
				visit[j]=0;
				x[step]=0;			
			}
			
		}
	}
	
} 
int main(void)
{
	int i,j;
	scanf("%d",&n);
 	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			scanf("%d",&arc[i][j]);
	visit[0]=1;
	x[0]=0;
	dfs(1,0);
	printf("%d ",bestCount);	
	return 0;
	
}

结果示例:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值