解法代码一:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
int n;
int mpt[20][20];
int dp[20][1<<20];
void solve()
{
int i,j,k,MAX=1<<n;
memset(dp,INF,sizeof(dp));
for(i=0;i<n;i++)
{
dp[i][1<<i]=mpt[0][i];
}
for(j=0;j<MAX;j++)
{
for(i=0;i<n;i++)
{
if((j&(1<<i))==0) continue; //注意运算符优先级
for(k=0;k<n;k++)
{
dp[i][j]=min(dp[i][j],dp[k][j&(~(1<<i))]+mpt[k][i]);
}
}
}
printf("%d\n",dp[0][MAX-1]);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&mpt[i][j]);
}
}
solve();
}
return 0;
}
///////////////////////////////////////////////////////////
解法代码二:
#include<iostream>
#include<cstdio>
using namespace std;
int n, g[20][20], r[20][20], f[20], ans = 0x7fffffff;
void Dfs(int now, int sum, int dis)
{
if (dis + r[now][1] >= ans)return; //如果最小距离仍然大于最优解,直接减枝
if (dis>ans)return;
if (sum == n)
{
ans = min(ans, dis + g[now][1]);
return;
}
for (int i = 1; i <= n; i++)
if (f[i] == 0)
{
f[i] = 1; Dfs(i, sum + 1, dis + g[now][i]); f[i] = 0;
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &g[i][j]), r[i][j] = g[i][j];
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
r[i][j] = min(r[i][j], r[i][k] + r[j][k]); //计算两点之间的最小距离
f[1] = 1;
Dfs(1, 1, 0);
printf("%d\n", ans);
return 0;
}