[BZOJ4152]The Captain

来源:互联网 发布:unity3d 摇杆控制角色 编辑:程序博客网 时间:2024/05/11 15:54

假设A,B,C三点,xA< xB< xC,从A到经过B到C一定不比直接从A到C更劣。y坐标同理。于是按x坐标和y坐标分别排序建边跑最短路即可。
代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#define ll long long#define pa pair<ll ,int>using namespace std;const int maxn=200010;const ll inf=100000000000000000;priority_queue<pa ,vector<pa > ,greater<pa > > q;int n;bool visit[maxn];ll dist[maxn];struct pt{    int x,y,id;}p[maxn];bool cmpx(pt a,pt b) {return a.x<b.x;}bool cmpy(pt a,pt b) {return a.y<b.y;}struct edge{    int t,w;    edge *next;}*con[maxn];void ins(int x,int y,int w){    edge *p=new edge;    p->t=y;    p->w=w;    p->next=con[x];    con[x]=p;}void dijkstra(){    for(int i=2;i<=n;i++) dist[i]=inf;    dist[1]=0;    q.push(make_pair(0,1));    while(!q.empty())    {        pa v=q.top();q.pop();        if(dist[v.second]!=v.first) continue;        for(edge *p=con[v.second];p!=NULL;p=p->next)            if(dist[p->t]>v.first+p->w)            {                dist[p->t]=v.first+p->w;                q.push(make_pair(dist[p->t],p->t));            }    }}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        {scanf("%d%d",&p[i].x,&p[i].y);p[i].id=i;}    sort(p+1,p+n+1,cmpx);    for(int i=1;i<n;i++)        ins(p[i].id,p[i+1].id,p[i+1].x-p[i].x),ins(p[i+1].id,p[i].id,p[i+1].x-p[i].x);    sort(p+1,p+n+1,cmpy);       for(int i=1;i<n;i++)        ins(p[i].id,p[i+1].id,p[i+1].y-p[i].y),ins(p[i+1].id,p[i].id,p[i+1].y-p[i].y);    dijkstra();    printf("%lld",dist[n]);         return 0;}