BZOJ4152The Captain[DIjkstra]

4152: [AMPPZ2014]The Captain

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 700  Solved: 266
[Submit][Status][Discuss]

Description

给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用。

 

Input

第一行包含一个正整数n(2<=n<=200000),表示点数。
接下来n行,每行包含两个整数x[i],y[i](0<=x[i],y[i]<=10^9),依次表示每个点的坐标。
 
 

 

Output

一个整数,即最小费用。

 

Sample Input

5
2 2
1 1
4 5
7 1
6 7

Sample Output

2

HINT

 

Source

n2建边肯定不行
min可以无视掉,建两条边
假如两点之间有第三个点,那么只要分别和第三个点建边就行了,这两点之间不需要
  • 所以每个点只需要向上下左右最靠近的点连边,排序即可
跑Dijkstra
//
//  main.cpp
//  bzoj4152thecaptain
//
//  Created by Candy on 9/7/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N=200005,INF=1e9+5;
inline int read(){
    int 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;
}
int n;
struct data{
    int x,y,id;
}p[N];
bool cmpx(data a,data b){
    return a.x<b.x;
}
bool cmpy(data a,data b){
    return a.y<b.y;
}

struct edge{
    int v,w,ne;
}e[N*4];
int h[N],cnt=0;
void ins(int u,int v,int w){
    cnt++;
    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    cnt++;
    e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
}

void buildGraph(){
    sort(p+1,p+1+n,cmpx);
    for(int i=1;i<=n-1;i++) ins(p[i].id,p[i+1].id,p[i+1].x-p[i].x);
    sort(p+1,p+1+n,cmpy);
    for(int i=1;i<=n-1;i++) ins(p[i].id,p[i+1].id,p[i+1].y-p[i].y);
}

struct hn{
    int u,d;
    bool operator <(const hn &rhs)const{return d>rhs.d;}
};
int d[N],done[N];
priority_queue<hn> q;
void dijkstra(int s){
    for(int i=1;i<=n;i++) d[i]=INF;
    d[s]=0;q.push((hn){s,0});
    while(!q.empty()){
        hn x=q.top();q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=1;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(d[v]>d[u]+e[i].w){
                d[v]=d[u]+e[i].w;
                q.push((hn){v,d[v]});
            }
        }
    }
}
int main(int argc, const char * argv[]) {
    n=read();
    for(int i=1;i<=n;i++) p[i].x=read(),p[i].y=read(),p[i].id=i;
    buildGraph();
    dijkstra(1);
    printf("%d",d[n]);
    return 0;
}

 

 
posted @ 2016-09-08 12:48  Candy?  阅读(344)  评论(0编辑  收藏  举报