【YBTOJ】最短路径
最短路径
题目大意:
给定一张 \(n\) 个点的带权无向图,求起点 \(0\) 到终点 \(n-1\) 的最短 Hamilton 路径。Hamilton 路径的定义是从 \(0\) 到 \(n-1\) 不重不漏地经过每个点恰好一次。
正文:
傻逼题。设 \(f_{i,j}\) 表示当前 \(i\) 点已走 \(j\) 状态的最短路:
\[f_{i,j}=\min_{k,l\cup i=j|i\not\in l}\{f_{k,l}+w_{k,i}\}
\]
代码:
const int N = 25, M = 1048580;
inline ll Read()
{
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
int n;
ll a[N][N], f[N][M];
int main()
{
n = Read();
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
a[i][j] = Read();
memset (f, 0x3f, sizeof f);
f[1][1] = 0;
for (int j = 0; j < (1 << n); j++)
for (int i = 1; i <= n; i++)
{
if (!((j >> i - 1) & 1)) continue;
for (int k = 1; k <= n; k++)
{
if (!((j >> k - 1) & 1) || i == k) continue;
f[i][j] = min(f[i][j], f[k][j ^ (1 << i - 1)] + a[i][k]);
}
}
printf ("%lld\n", f[n][(1 << n) - 1]);
return 0;
}