这道题我们首先会想到优化建图;
线段树优化建图?不对不对;
那么就具体问题具体分析:
浅显的性质:有可能选择的边一定存在于按x或y排序的相邻的两个点之间;
那么O(n)建图,然后dijkstra就好了;
#include <bits/stdc++.h>
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
class node{
public:
int x,y,id;
}points[200010];
bool cmp1(node x,node y){
return x.x<y.x;
}
bool cmp2(node x,node y){
return x.y<y.y;
}
int head[200010],cnt;
class littlestar{
public:
int to,nxt,w;
void add(int u,int v,int gg){
to=v; nxt=head[u];
head[u]=cnt; w=gg;
}
}star[800010];
priority_queue<pair<int,int> >qwq;
int dis[200010],vis[200010];
void dijkstra()
{
qwq.push(make_pair(0,1));
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
while(qwq.size()){
int u=qwq.top().second;
qwq.pop();
if(vis[u]) continue;
vis[u]=1;
for(register int i=head[u];i;i=star[i].nxt){
int v=star[i].to;
if(dis[v]>dis[u]+star[i].w){
dis[v]=dis[u]+star[i].w;
qwq.push(make_pair(-dis[v],v));
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
inc(i,1,n) scanf("%d%d",&points[i].x,&points[i].y),points[i].id=i;
sort(points+1,points+1+n,cmp1);
inc(i,2,n){
star[++cnt].add(points[i-1].id,points[i].id,points[i].x-points[i-1].x);
star[++cnt].add(points[i].id,points[i-1].id,points[i].x-points[i-1].x);
}
sort(points+1,points+1+n,cmp2);
inc(i,2,n){
star[++cnt].add(points[i-1].id,points[i].id,points[i].y-points[i-1].y);
star[++cnt].add(points[i].id,points[i-1].id,points[i].y-points[i-1].y);
}
dijkstra();
cout<<dis[n];
}
/*
5
2 2
1 1
4 5
7 1
6 7
*/
原文:https://www.cnblogs.com/kamimxr/p/12018802.html