http://acm.hdu.edu.cn/showproblem.php?pid=5418
旅行商问题(Traveling Salesman Problem,TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。
本题题意就是这个意思,这里贴上 回溯法和枚举法 两种代码。
枚举法代码+回溯法两种写法:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 20;
int mat[N][N];
int n,m;
int dp[1<<17][N];
const int INF = 0x3f3f3f3f;
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) mat[i][j]=0;
else mat[i][j] = INF;
}
return;
}
void floyed()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
mat[i][j] = min(mat[i][j],mat[i][k]+mat[k][j]);
return;
}
int work()
{
for(int i=1;i<(1<<n);i++)//先模拟状态再模拟城市
{
for(int j=1;j<=n;j++)
{
if(((i>>(j-1))&1)!=0)
{
for(int k=1;k<=n;k++)
{
if(((i>>(k-1))&1)==0)
{
int sta = i|(1<<(k-1));
dp[sta][k] = min(dp[sta][k],dp[i][j]+mat[j][k]);
}
}
}
}
}
int ans =INF;
for(int i=2;i<=n;i++) ans = min(ans,dp[(1<<n)-1][i]+mat[i][1]);
return ans;
}
int dfs(int sta,int x)
{
if(dp[sta][x]) return dp[sta][x];
int mis= INF;
for(int i=1;i<=n;i++)
{
if( i==1 && sta == (1<<n)-1)
mis = min(mis,mat[x][i]);
if(sta>>(i-1) & 1) continue;
mis = min(mis,dfs(sta|1<<(i-1),i) + mat[x][i]);
}
return dp[sta][x] = mis;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
while(m--)
{
int st,ed,w;
scanf("%d%d%d",&st,&ed,&w);
mat[st][ed] = mat[ed][st] = min(mat[st][ed],w);
}
if(n==1)
{
printf("0\n");
continue;
}
floyed();
/* memset(dp,INF,sizeof(dp));
dp[1][1]=0;
printf("%d\n",work()); */ //枚举法
memset(dp,0,sizeof(dp));//回溯法dp数组初始化方式
printf("%d\n",dfs(1,1));//回溯法
}
return 0;
}