问题 H: 平面旅行(枚举)

牛牛最近在玩某款游戏,其地图可以看成一个平面直角坐标系。
地图上存在n个小镇,小镇从1到n编号。第i个小镇的坐标为(xi,yi)。定义两个小镇的距离为曼哈顿距离,比如小镇i到小镇j的距离为|xi−xj|+|yi−yj|,其中,|a|表示取a的绝对值。
牛牛在m个小镇建立了传送门,也就是说,牛牛可以在任何时候任何瞬间不花费任何代价,直接到达这m个小镇的任何一个。
牛牛一开始在小镇1,牛牛想按1到n的顺序访问所有小镇按顺序做任务,问牛牛需要走过的最短距离是多少。
牛牛可以提前到达某个小镇,但是必须做完前一个小镇的任务,才能做下一个小镇的任务。做任务本身不会增加距离。
输入
第一行输入两个整数n,m,表示地图上小镇的数目和牛牛建立了传送门的小镇数量。
随后n行,其中第i行输入两个整数xi,yi,第i个小镇的坐标。
随后一行输入m个整数,表示建立了传送门的小镇编号。
输出
一行一个整数表示答案。
样例输入 Copy
6 2
-10 -10
10 10
0 0
1 -1
-1 1
2 1
3 6
样例输出 Copy
21
提示
样例解释:
牛牛一开始在小镇1,完成任务后,传送到小镇6。
步行至小镇2,累计17点距离,完成任务后,传送到小镇3。
在小镇3完成任务,累计17点距离。
步行到小镇4完成任务,累计19点距离,传送到小镇3。
步行到小镇5完成任务,累计21点距离。
传送到小镇6并完成任务。
共计21点距离。

对于20%的数据有m=0。
对于40%的数据有m=1。
对于60%的数据有n,m≤300。
对于100%的数据有1≤n≤5000,0≤m≤n,−10000≤xi,yi≤10000
数据保证没有任意两个小镇在同一坐标下。

思路:

由于必须要完成\(i-1\)的任务才能完成\(i\)的任务。
所以对于第\(i\)个点来说,有两种最优的可能:
\(1.\)\(i-1\)直接到达\(i\)
\(2.\)\(i-1\)到达传送门,再从传送门到达\(i\);
由于到达传送门是没有代价的,所以\(2\)的代价只有后者。
枚举所有的传送门就可以得到最小值。
时间复杂度\(O(N^{2})\)

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PLL;
typedef pair<int, int>PII;
typedef pair<double, double>PDD;
#define I_int ll
inline ll read()
{
    ll x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a, ll b, ll p)
{
    ll res = 1;
    while(b)
    {
        if(b & 1)res = res * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return res;
}
const int inf = 0x3f3f3f3f;
#define PI acos(-1)
const int maxn=5100;
 
ll n,m;
ll x[maxn],y[maxn],a[maxn],vis[maxn];
 
ll cul(int i,int j){
    return abs(x[i]-x[j])+abs(y[i]-y[j]);
}
 
int main(){
    n=read,m=read;
    rep(i,1,n) x[i]=read,y[i]=read;
    rep(i,1,m){
        a[i]=read;
        vis[a[i]]=1;
    }
    ll res=0;
    for(int i=2;i<=n;i++){
        if(vis[i]) continue;
        ll tmp=cul(i-1,i);///直接到达
        for(int j=1;j<=m;j++){
            tmp=min(tmp,cul(a[j],i));
        }
        ///cout<<i<<" "<<tmp<<endl;
        res+=tmp;
    }
    printf("%lld\n",res);
     
     
    return 0;
}
 
 
 
 
 
 
 
 
posted @ 2021-06-12 09:12  OvO1  阅读(61)  评论(0编辑  收藏  举报