转自:http://blog.csdn.net/huzecong/article/details/8576908
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
#define maxn 10005
using namespace std;
struct point
{
int x,y,id;
bool operator < (const point &cmp)const
{
if(x==cmp.x)return y<cmp.y;
return x<cmp.x;
}
} p[maxn];
struct BIT
{
int min_val,pos;
void init()
{
min_val=inf;
pos=-1;
}
} bit[maxn];
struct Edge
{
int s,e,w;
bool operator < (const Edge &cmp)const
{
return w<cmp.w;
}
} E[maxn<<2];
int tot,n,k;
void update(int x,int val,int pos)//更新 1-x 上的最小值
{
for(int i=x; i>=1; i-=lowbit(i))
if(bit[i].min_val > val)
bit[i].min_val=val,bit[i].pos=pos;
}
int query(int x,int m)//这里其实求的是 x-m 上的最小值
{
int val=inf,pos=-1;
for(int i=x; i<=m; i+=lowbit(i))
if(bit[i].min_val < val)
val=bit[i].min_val,pos=bit[i].pos;
return pos;
}
void addedge(int s,int e,int v)
{
E[tot].s=s;
E[tot].e=e;
E[tot++].w=v;
}
int dist(int a,int b)
{
return abs(p[a].x-p[b].x)+abs(p[a].y-p[b].y);
}
int set[maxn];
int find(int x)
{
if(x!=set[x])
return set[x]=find(set[x]);
return x;
}
int a[maxn],b[maxn];
int Manhattan_MST()
{
for(int i=1; i<=n; i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id=i;
}
for(int dir=1; dir<=4; dir++)
{
if(dir==2 || dir==4)
{
for(int i=1; i<=n; i++)
swap(p[i].x,p[i].y);
}
else if(dir==3)
for(int i=1; i<=n; i++)
p[i].x=-p[i].x;
sort(p+1,p+1+n);//sort by x
for(int i=1; i<=n; i++)
a[i]=b[i]=p[i].y-p[i].x;
sort(b+1,b+1+n);//将 y-x 离散化
int m=unique(b+1,b+1+n)-b;
for(int i=1; i<m; i++)bit[i].init();
for(int i=n; i>=1; i--)//这里y-x从大到小进入BIT。那么这里保证了y-x 的有序。
{
int pos=lower_bound(b+1,b+m,a[i])-b;
int ans = query(pos,m-1);
if(ans!=-1)addedge(p[i].id,p[ans].id,dist(i,ans));
update(pos,p[i].x+p[i].y,i);//求出加入到BIT中的比当前点y-x大的y+x的值。
}
}
sort(E,E+tot);
for(int i=0; i<=n; i++)set[i]=i;
int cnt=n-k;
for(int i=0; i<tot; i++)
{
int x=find(E[i].s);
int y=find(E[i].e);
if(x==y)continue;
else
{
set[x]=y;
cnt--;
if(cnt==0)return E[i].w;
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
tot=0;
printf("%d\n",Manhattan_MST());
}
return 0;
}