====================================================================================================================================================
哈密顿回路: 从一个城市出发,经过每一个城市恰好一次,然后回到出发城市。
求解: 对于给定的无向图,就是考察图中所有顶点的全排列
满足: ①相邻顶点之间存在边,②最后一个顶点和第一个顶点之间存在边
时间复杂度: 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;
}
结果示例: