POJ 3241 Object Clustering 莫队算法

第n-k大曼哈顿距离,莫队算法裸题


Object Clustering

Time Limit: 2000MS   Memory Limit: 131072K
Total Submissions: 1584   Accepted: 366

Description

We have (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 (ab ≤ 500). The resemblance of
object i and object j is defined by dij = |a- aj| + |b- 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 (< 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

[Submit]   [Go Back]  
[Status]   [Discuss]

/* ***********************************************
Author        :CKboss
Created Time  :2014年12月20日 星期六 00时27分00秒
File Name     :POJ3241.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

const int maxn=22000;
const int INF=0x3f3f3f3f;

int n,k;

struct Edge
{
	int u,v,w;
}edge[maxn<<2];
int tot;

bool cmp_E(Edge a,Edge b)
{
	return a.w<b.w;
}

struct Point
{
	int x,y,id;
}pt[maxn];

bool cmp_P(Point a,Point b)
{
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}

int lowbit(int x) { return x&(-x); }

int C[4000],D[4000];

void update(int id,int pos,int val)
{
	pos+=1000;
	for(int i=pos;i;i-=lowbit(i))
	{
		if(C[i]>val)
		{
			C[i]=val; D[i]=id;
		}
	}
}

void query(int id,int pos,int val)
{
	pos+=1000;
	int Fr=-1,ret=INF;
	for(int i=pos;i<4000;i+=lowbit(i))
	{
		if(ret>C[i])
		{
			ret=C[i]; Fr=D[i];
		}
	}
	if(Fr!=-1) edge[tot++]=(Edge){id,Fr,ret-val};
}

void gao()
{
	memset(C,63,sizeof(C));
	sort(pt,pt+n,cmp_P);
	for(int i=n-1;i>=0;i--)
	{
		int pos=pt[i].y-pt[i].x;
		int sum=pt[i].y+pt[i].x;
		int id=pt[i].id;
		query(id,pos,sum);
		update(id,pos,sum);
	}
}

int fa[maxn];

int find(int x)
{
	if(x==fa[x]) return x;
	return fa[x]=find(fa[x]);
}

bool merge(int a,int b)
{
	a=find(a); b=find(b);
	if(a==b) return false;
	fa[a]=b;
	return true;
}

int solve()
{
	if(n==k) return 0;

	tot=0;

	gao();

	for(int i=0;i<n;i++)
		swap(pt[i].x,pt[i].y);
	gao();

	for(int i=0;i<n;i++)
		pt[i].y=-pt[i].y;
	gao();

	for(int i=0;i<n;i++)
		swap(pt[i].x,pt[i].y);
	gao();

	for(int i=0;i<n;i++) fa[i]=i;
	sort(edge,edge+tot,cmp_E);
	for(int i=0;i<tot;i++)
	{
		if(merge(edge[i].u,edge[i].v)==true)
		{
			n--; if(n==k) return edge[i].w;
		}
	}

	return -1;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	while(scanf("%d%d",&n,&k)!=EOF)
	{
		for(int i=0;i<n;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			pt[i].x=x; pt[i].y=y; pt[i].id=i;
		}
		printf("%d\n",solve());
	}

    return 0;
}
时间: 2024-10-21 02:36:41

POJ 3241 Object Clustering 莫队算法的相关文章

平面点曼哈顿最小生成树——POJ 3241 Object Clustering

对应POJ题目:点击打开链接 Object Clustering Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 1697   Accepted: 418 Description We have N (N ≤ 10000) objects, and wish to classify them into several groups by judgement of their resemblance. To simply

poj 3241 Object Clustering 曼哈顿最小生成树

题意: 平面上有n个点,现在把他们分成k个集合,使得每个集合中的每个点都至少有一个本集合的点之间的曼哈顿距离不大于X,求最小的X. 分析: 转化为求n个点生成完全图的最小生成树的第k大边.接下来有几个重点. 1)根据莫队算法,由于边权是点的曼哈顿距离,每个点只需要跟周围8个方向中每个方向最近的点连边,这样算出的图与用完全图算出的最小生成树一样,涉及的边却大大减少. 2)用树状数组维护y右偏45度的最近点,每个点以y-x的位置,y+x的值放入树状数组,由于每次是查询区间(pos,last)的情况,

POJ 3241 Object Clustering 曼哈顿距离最小生成树

题目大意:求出曼哈顿距离最小生成树上的第k大边权. 思路:首先,你要了解:http://blog.csdn.net/acm_cxlove/article/details/8890003 也就是说,我们以每一个点为中心,把平面分成8个部分,每一个部分我们只需要离这个点最近的点.然后加上建一条边连接这个边和最近的点.然后就是MST. 听说这个算法是莫队算法的基础,我现在就去学. CODE: #include <cstdio> #include <cstring> #include &l

poj 3241 Object Clustering (曼哈顿最小生成树)

Object Clustering Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 2640   Accepted: 806 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

POJ 3241 Object Clustering(Manhattan MST)

题目链接:http://poj.org/problem?id=3241 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 ob

POJ 3241 Object Clustering 二维平面曼哈顿距离最小生成树

题目链接:点击打开链接 题意: 给定二维平面上的n个点坐标,常数k 下面n行给出坐标 求一个最小生成树,问第k大的边是多少. 任意两个点间建一条边的花费是其曼哈顿距离. 思路:转自:点击打开链接 一.曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价. 朴素的算法可以用O(N2)的Prim,或者处理出所有边做Kruskal,但在这里总边数有O(N2)条,所以Kruskal的复杂度变成了O(N2logN

莫队算法

Beautiful Girl 题意 给定一个长度为 n 的序列 a[1], a[2], ..., a[n] . m 组询问 (l, r, K) , 求区间 [l, r] 去除重复的数之后的第 K 小. n, m <= 100000 . 分析 莫队算法 + 值域分块. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include &

BZOJ4241 历史研究 莫队算法 堆

欢迎访问~原文出处--博客园-zhouzhendong&AK 去博客园看该题解 题目 Description IOI国历史研究的第一人--JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记.JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件. 日记中记录了连续N天发生的时间,大约每天发生一件. 事件有种类之分.第i天(1<=i<=N)发生的事件的种类用一个整数Xi表示,Xi越大,事件的规模就越大. JOI教授决定用如下的方法分析这些日记: 1.

CodeForces - 86D 莫队算法

http://codeforces.com/problemset/problem/86/D 莫队算法就是调整查询的顺序,然后暴力求解. 每回可以通过现有区间解ans(l,r)得到区间(l+1,r),(l-1,r),(l,r+1),(l,r-1)的区间解. 调整方式http://blog.csdn.net/bossup/article/details/39236275 这题比那个还要简单,查询的是K^2*Z,很清楚就是莫队算法,然而做的时候没有学过,回来补题补到 关键是我一直没明白为什么重载小于号