4152: [AMPPZ2014]The Captain
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1517 Solved: 603
[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
2 2
1 1
4 5
7 1
6 7
Sample Output
2
HINT
Source
按横坐标排序,相邻点建边
按纵坐标排序,相邻点建边
dijkstra可过
#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
#define N 200005
using namespace std;
typedef pair<ll,int>pii;
int n,tot,vis[N],hd[N],d[N];
struct P{int x,y,id;}a[N];
struct edge{int v,w,next;}e[N*];
bool cmp1(P a,P b){return a.x<b.x;}
bool cmp2(P a,P b){return a.y<b.y;}
void add(int u,int v,int w){
e[++tot].v=v;
e[tot].next=hd[u];
e[tot].w=w;
hd[u]=tot;
}
void adde(int u,int v,int w){add(u,v,w);add(v,u,w);}
priority_queue<pii,vector<pii>,greater<pii> >q;
void dijkstra(){
for(int i=;i<=n;i++)d[i]=<<;
d[]=;q.push(mp(,));
while(!q.empty()){
pii x=q.top();q.pop();
int u=x.second;
if(vis[u])continue;vis[u]=;
for(int i=hd[u];i;i=e[i].next){
int v=e[i].v;
if(vis[v])continue;
if(d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
q.push(mp(d[v],v));
}
}
}
} int main(){
scanf("%d",&n);
for(int i=;i<=n;a[i].id=i,i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a+,a++n,cmp1);
for(int i=;i<n;i++)
adde(a[i].id,a[i+].id,abs(a[i+].x-a[i].x));
sort(a+,a++n,cmp2);
for(int i=;i<n;i++)
adde(a[i].id,a[i+].id,abs(a[i+].y-a[i].y));
dijkstra();printf("%d",d[n]);
return ;
}