>Link
牛客1030普及T2
>Description
给出一个有n个点的图,每个点都有对应的坐标
其中每两个点之间都有且仅有一条路径,路径长为两点间的哈密顿距离
这n个点中有m个固定的点,我们可以在任何时候任意位置花费0代价到达这m个点中的任何一个
要求求一条最短路,这条路径中一定存在1、2、3…n的到达顺序
>解题思路
两点之间的路径权值为哈密顿距离,因此我们知道从
i
i
i步行到
j
j
j的最短路一定是直接走两点之间的那一条路径
传送门的情况,我们就直接O(nm)暴力求出从每个传送门到每个点的最优代价,原理同上
最后答案就累加每
[
i
,
i
+
1
]
[i,i+1]
[i,i+1]之间的最短距离
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 5005
#define int long long
using namespace std;
int n, m, x[N], y[N], s[N], dis[N][N], minn[N], ans;
bool mark[N];
signed main()
{
memset (minn, 0x7f, sizeof (minn));
scanf ("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) scanf ("%lld%lld", &x[i], &y[i]);
for (int i = 1; i <= m; i++)
{
scanf ("%lld", &s[i]);
mark[s[i]] = 1;
}
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
if (!mark[j])
minn[j] = min (minn[j], abs (x[s[i]] - x[j]) + abs (y[s[i]] - y[j]));
for (int i = 1; i < n; i++)
{
if (mark[i + 1]) continue;
ans += min (minn[i + 1], abs (x[i] - x[i + 1]) + abs (y[i] - y[i + 1]));
//要么用传送门,要么直接步行
}
printf ("%lld", ans);
return 0;
}