【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;
}
posted @ 2021-07-20 20:05  Jayun  阅读(80)  评论(0编辑  收藏  举报