BZOJ4152 [AMPPZ2014]The Captain

Link
(x)坐标排序然后相邻的建边,再(y)坐标排序然后相邻的建边。
易证这样子两个点之间的最短路一定会被建出来。

#include<bits/stdc++.h>
#define pi pair<int,int>
#define pb push_back
#define fi first
#define se second
using namespace std;
const int N=200007;
pi a[N];int p[N],dis[N],vis[N];vector<pi>E[N];priority_queue<pi>q;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
void add(int u,int v,int w){E[u].pb(pi(v,w)),E[v].pb(pi(u,w));}
int main()
{
    int n=read(),i;
    for(i=1;i<=n;++i) a[i].fi=read(),a[i].se=read(),p[i]=i;
    sort(p+1,p+n+1,[](int i,int j){return a[i].fi<a[j].fi;});
    for(i=1;i<n;++i) add(p[i],p[i+1],a[p[i+1]].fi-a[p[i]].fi);
    sort(p+1,p+n+1,[](int i,int j){return a[i].se<a[j].se;});
    for(i=1;i<n;++i) add(p[i],p[i+1],a[p[i+1]].se-a[p[i]].se);
    memset(dis,0x3f,sizeof dis),q.push(pi(dis[1]=0,1));
    while(!q.empty())
    {
	i=q.top().se,q.pop();if(vis[i])continue;vis[i]=1;
	for(pi x:E[i])if(dis[x.fi]>dis[i]+x.se)dis[x.fi]=dis[i]+x.se,q.push(pi(-dis[x.fi],x.fi));
    }
    printf("%d",dis[n]);
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11792038.html