tyvj4221 货车漂移

背景

蒟蒻中学的蒟蒻遇到了一些小问题。

描述

蒟蒻考完noip也就要回家种田了,他老家的田地在s点,可是种子市场在e点,为了购买种子,中途要经过很多城市,这导致快递费非常的贵(因为快到双11了),于是他准备自己开车,可现在油价也不便宜,他想尽量省一些油。

已知蒟蒻掌握着熟练的漂移技巧,当他在点A(x1,y1)时,他可以使用漂移到达点B(x2,y2),这样耗费的油量为|x1-x2|和|y1-y2|(x差值的绝对值和y差值的绝对值)中较小的那一个。

现在蒟蒻要从s点到e点,请问他最少消耗多少油?

输入格式

第一行三个数 n,s,e,代表有n个点,起点为s号点,终点为e号点

第2到第n+1行,第i行两个数 代表一个点(x,y) 

点的标号从1开始

输出格式

一行一个数 为消耗的最少油量

 

备注

样例输入1

5 1 5

1 1

2 1

3 1

4 1

5 1

 

样例输出1

0

 

样例解释1

直接从1号点(1,1)漂移到5号点(5,1)花费为1-1=0

 

样例输入2

5 1 5

2 1

3 3

5 2

1 4

6 6

 

 

样例输出2

2

 

样例解释2

从1号点(2,1)漂移到3号点(5,2)花费为2-1=1

从3号点(5,2)漂移到终点5号点(6,6)花费为6-5=1

这是一个消耗油量最少的解 为2

 

数据范围:

对于50%的数据 2<=n<=3000

对于100%的数据 2<=n,s,e<=100000  0<=x,y<=1000000000

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define maxn 200005
#define inf ~0U>>1
using namespace std;
struct point{
    int x;
    int y;
    int pos;
};
struct orz{
    int p;
    int d;
    friend bool operator < (orz a,orz b){
        return a.d > b.d;
    }
};
struct edge{
    int v;
    int w;
};
priority_queue< orz > ss;
vector<edge> g[maxn];
point pt[maxn];
int flag = 0,v[maxn],d[maxn],n,s,t;
bool cmpa(point a,point b){
    return a.x < b.x;
}
bool cmpb(point a,point b){
    return a.y < b.y;
}
void init(){
    cin>>n>>s>>t;
    int tx,ty;
    for(int i = 1;i <= n;i++){
        scanf("%d%d",&tx,&ty);
        pt[i].x = tx;
        pt[i].y = ty;
        pt[i].pos = i;
    }
    for(int i = 1;i <= n;i++) d[i] = inf;
    sort(pt+1,pt+1+n,cmpa);
    edge tmp;
    for(int i = 1;i < n;i++){
        tmp.w = pt[i+1].x - pt[i].x;
        tmp.v = pt[i + 1].pos;
        g[pt[i].pos].push_back(tmp);
        tmp.v = pt[i].pos;
        g[pt[i+1].pos].push_back(tmp);
    }
    sort(pt+1,pt+1+n,cmpb);
    for(int i = 1;i < n;i++){
        tmp.w = pt[i+1].y - pt[i].y;
        tmp.v = pt[i + 1].pos;
        g[pt[i].pos].push_back(tmp);
        tmp.v = pt[i].pos;
        g[pt[i+1].pos].push_back(tmp);
    }
}
void dij(){
    orz tmp;
    d[s] = 0;
    tmp.p = s;
    tmp.d = 0;
    ss.push(tmp);
    flag++;
    int to,wei,x,dd;
    edge j;
    while(!ss.empty()){
        tmp = ss.top();
        ss.pop();
        x = tmp.p;
        dd = tmp.d;
        if(v[x] == flag) continue;
        v[x] = flag;
        for(int i = 0;i < g[x].size();i++){
            j = g[x][i];
            to = j.v;
            wei = j.w;
            if(d[to] > dd + wei){
                d[to] = dd + wei;
                tmp.d = dd + wei;
                tmp.p = to;
                ss.push(tmp);
            }
        }
    }
    cout<<d[t];
}
int main(){

    init();
    dij();
    return 0;
}

 

posted @ 2016-09-08 16:03  ACforever  阅读(149)  评论(0编辑  收藏  举报