题意
传送门 POJ 3311
题解
考虑到节点可以多次经过, F l o y d − W a r s h a l l Floyd-Warshall Floyd−Warshall 求图中任意两点间的最短路;转化为旅行商问题,状态压缩 D P DP DP 求解即可。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 11
int n, d[maxn][maxn], dp[maxn][1 << maxn];
void floyd()
{
for (int k = 0; k < n; k++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
}
}
int rec(int v, int s)
{
if (dp[v][s] != -1) return dp[v][s];
if (v == 0 && s == (1 << n) - 1) return dp[v][s] = 0;
int res = inf;
for (int i = 0; i < n; i++)
{
if (!(s >> i & 1))
{
res = min(res, rec(i, s | 1 << i) + d[v][i]);
}
}
return dp[v][s] = res;
}
int main()
{
while (~scanf("%d", &n) && n)
{
++n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &d[i][j]);
}
}
floyd();
memset(dp, -1, sizeof(dp));
printf("%d\n", rec(0, 0));
}
return 0;
}