熟悉了一下kuangbin模板 T_T
对于每个结点来说,只有四个方向的结点最近距离需要考虑,方向问题用翻转操作处理掉,然后是偏序问题,考虑y轴右边45度,对x,y排序,对
y-x离线,对x+y树状数组
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 20004
int s[maxn],b[maxn];
int n,k,tot;
struct BIT
{
int id;
int w;
void init()
{
w=INF;
id=-1;
}
} c[maxn];
struct node
{
int x,y;
int id;
friend bool operator < (node A,node B)
{
if(A.x==B.x) return A.y<B.y;
return A.x<B.x;
}
} p[maxn];
struct edge
{
int u,v;
int w;
friend bool operator < (edge A,edge B)
{
return A.w<B.w;
}
} edg[8*maxn];
int lowbit(int x)
{
return x&-x;
}
void update(int x,int val,int id)
{
for(; x>0; x-=lowbit(x))
{
if(c[x].w>val)
{
c[x].w=val;
c[x].id=id;
}
}
}
int query(int l,int r)
{
int id=-1,w=INF;
for(; l<=r; l+=lowbit(l))
{
if(c[l].w<w)
{
w=c[l].w;
id=c[l].id;
}
}
return id;
}
int root(int x)
{
return x==s[x]?x:s[x]=root(s[x]);
}
int dist(int x,int y)
{
return abs(p[x].x-p[y].x)+abs(p[x].y-p[y].y);
}
void Mht()
{
for(int i=0; i<4; i++)
{
if(i==1||i==3)
{
for(int i=0; i<n; i++)
{
swap(p[i].x,p[i].y);
}
}
else if(i==2)
{
for(int i=0; i<n; i++)
{
p[i].x=-p[i].x;
}
}
sort(p,p+n);
for(int i=0; i<n; i++) b[i]=p[i].y-p[i].x;
sort(b,b+n);
int len=unique(b,b+n)-b;
for(int i=0; i<=len; i++) c[i].init();
for(int i=n-1; i>=0; i--)
{
int pos=lower_bound(b,b+len,p[i].y-p[i].x)-b+1;
int id=query(pos,len);
if(id!=-1) edg[tot].u=p[i].id,edg[tot].v=p[id].id,edg[tot++].w=dist(i,id);
update(pos,p[i].x+p[i].y,i);
}
}
}
int solve(int n,int k)
{
tot=0;
Mht();
sort(edg,edg+tot);
for(int i=0; i<=n; i++) s[i]=i;
for(int i=0; i<tot; i++)
{
int x=root(edg[i].u);
int y=root(edg[i].v);
if(x!=y)
{
s[x]=y;
k--;
if(!k) return edg[i].w;
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF&&n)
{
for(int i=0; i<n; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id=i;
}
int ans=solve(n,k);
printf("%d\n",ans);
}
}