『算法-ACM竞赛-POJ』 3241Object Clustering曼哈顿距离最小生成树

『算法-ACM 竞赛-POJ』 3241Object Clustering 曼哈顿距离最小生成树

Object Clustering

Description

We have N (N ≤ 10000) objects, and wish to classify them into several groups by judgement of their resemblance. To simply the model, each object has 2 indexes a and b (a, b ≤ 500). The resemblance of object i and object j is defined by dij = |ai - aj| + |bi - bj|, and then we say i is dij resemble to j. Now we want to find the minimum value of X, so that we can classify the N objects into K (K < N) groups, and in each group, one object is at most X resemble to another object in the same group, i.e, for every object i, if i is not the only member of the group, then there exists one object j (i ≠ j) in the same group that satisfies dij ≤ X

Input

The first line contains two integers N and K. The following N lines each contain two integers a and b, which describe a object.

Output

A single line contains the minimum X.

Sample Input

6 2
1 2
2 3
2 2
3 4
4 3
3 1
Sample Output

2
Source

POJ Monthly–2007.08.05, Li, Haoyuan
题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<bitset>
#include<set>
#include<stack>
#include<map>
#include<list>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pi=acos(-1.0);
const double E=2.718281828459;
const ll mod=1e8+7;
const int INF=0x3f3f3f3f;

int n,k;

struct node{
int x;
int y;
int id;
bool friend operator<(node a,node b){
return a.x==b.x?a.y<b.y:a.x<b.x;
///保证树状数组更新和查询时不会遗漏
}
}point[10005];

struct edge{
int s;
int e;
int c;
bool friend operator<(edge a,edge b){
return a.c<b.c;
}
}load[40000];
int sign=0;
int p[10005];
int find(int x){
return p[x]==x?x:p[x]=find(p[x]);
}

void kruskal(){
for(int i=1;i<=n;i++)
p[i]=i;
sort(load+1,load+1+sign);
int cnt=0;
for(int i=1;i<=sign;i++){
int x=find(load[i].s);
int y=find(load[i].e);
if(x!=y){
cnt++;
p[x]=y;
if(cnt==n-k){
printf("%d\n",load[i].c);
return ;
}
}
}
}

int id[10005]; ///y-x为索引的编号
int xy[10005]; ///y-x为索引 x+y的最小值

void update(int index,int minn,int s) ///index:y-x minn:x+y s:编号
{
index+=1000;
for(int i=index;i>=1;i-=(i&(-i))){
if(xy[i]>minn){
xy[i]=minn;
id[i]=s;
}
}
}

void query(int index,int minn,int s) ///index:y-x minn:x+y s:编号
{
index+=1000;
int e=-1,c=INF;
///现在以编号s为原点,查询y-x>=index的点中x+y的最小值
for(int i=index;i<10000;i+=(i&(-i))){
if(xy[i]<c){
e=id[i];
c=xy[i];
}
}
if(e!=-1)
load[++sign]=edge{s,e,c-minn};
}

void build_edge()
{
/// 以(xi,yi)为原点,对于第1区域内的点(x,y)满足条件
/// x>=xi,y-x>=yi-xi,(x+y)最小
sort(point+1,point+1+n);
memset(id,-1,sizeof(id));
fill(xy,xy+10005,INF);
///按照x升序
///保证后面查询时,x都比当前的x大
for(int i=n;i>=1;i--){
int index=point[i].y-point[i].x;
int minn=point[i].x+point[i].y;
query(index,minn,point[i].id);
update(index,minn,point[i].id);
}
}

int main() ///第K大边
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d %d",&point[i].x,&point[i].y);
point[i].id=i;
}
///1象限建边
build_edge();

///2象限建边
for(int i=1;i<=n;i++)
swap(point[i].x,point[i].y);
build_edge();

///3象限建边
for(int i=1;i<=n;i++)
point[i].x=-point[i].x;
build_edge();

///4象限建边
for(int i=1;i<=n;i++)
swap(point[i].x,point[i].y);
build_edge();
kruskal();
return 0;
}

『算法-ACM竞赛-POJ』 3241Object Clustering曼哈顿距离最小生成树
https://chiamzhang.github.io/2024/06/29/『算法-ACM竞赛-POJ』 3241Object Clustering曼哈顿距离最小生成树/
Author
Chiam
Posted on
June 29, 2024
Licensed under