易证我们走的时候只会从某一层的某端点走向另一端点、然后走向下一层的某端点..
所以建图然后dijkstra就行了
调了一年以后发现dijkstra写错了
1 #include<bits/stdc++.h> 2 #define pa pair<ll,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=4e5+10; 7 const ll inf=1e18; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 struct Edge{ 17 int b,ne;ll l; 18 }eg[maxn*4]; 19 struct Node{ 20 ll x,y,l; 21 }pos[maxn]; 22 int N,egh[maxn],ect; 23 ll dd[maxn]; 24 bool flag[maxn]; 25 priority_queue<pa,vector<pa>,greater<pa> > q; 26 27 inline bool cmp(Node a,Node b){return a.l<b.l;} 28 inline void adeg(int a,int b,ll l){ 29 eg[++ect].b=b;eg[ect].ne=egh[a];eg[ect].l=l;egh[a]=ect; 30 } 31 inline ll dis(int a,int b){return abs(pos[a].x-pos[b].x)+abs(pos[a].y-pos[b].y);} 32 33 void dijkstra(){ 34 CLR(dd,-1); 35 dd[1+N]=0;q.push(make_pair(0,1+N)); 36 while(!q.empty()){ 37 int p=q.top().second;q.pop(); 38 if(flag[p]) continue; 39 flag[p]=1; 40 for(int i=egh[p];i;i=eg[i].ne){ 41 int b=eg[i].b; 42 if(dd[b]==-1||dd[b]>dd[p]+eg[i].l){ 43 dd[b]=dd[p]+eg[i].l; 44 q.push(make_pair(dd[b],b)); 45 } 46 } 47 } 48 } 49 50 int main(){ 51 //freopen(".in","r",stdin); 52 int i,j,k; 53 N=rd(); 54 for(i=1;i<=N;i++) 55 pos[i].x=rd(),pos[i].y=rd(),pos[i].l=max(pos[i].x,pos[i].y); 56 pos[N+1].x=0,pos[N+1].y=0,pos[N+1].l=0; 57 N++; 58 sort(pos+1,pos+N+1,cmp); 59 int lst1=-1,lst2=-1; 60 int la=-1,lb=-1; 61 for(i=N,j=N,k=N;i;i){ 62 int aa=-1,bb=-1; 63 for(;pos[j].l==pos[i].l&&j;j--){ 64 if(aa==-1||pos[j].x<pos[aa].x||(pos[j].x==pos[aa].x&&pos[j].y>pos[aa].y)) aa=j; 65 if(bb==-1||pos[j].y<pos[bb].y||(pos[j].y==pos[bb].y&&pos[j].x>pos[bb].x)) bb=j; 66 } 67 if(lst1==-1) lst1=aa; 68 if(lst2==-1) lst2=bb; 69 if(la!=-1) adeg(aa+N,la,dis(la,aa)),adeg(bb+N,la,dis(la,bb)); 70 if(lb!=-1) adeg(aa+N,lb,dis(lb,aa)),adeg(bb+N,lb,dis(lb,bb)); 71 adeg(aa,bb+N,dis(aa,bb));adeg(bb,aa+N,dis(aa,bb)); 72 la=aa,lb=bb; 73 } 74 dijkstra(); 75 printf("%I64d ",min(dd[lst1+N],dd[lst2+N])); 76 return 0; 77 }