题意:求最小生成树第K大的边权值

思路:

如果暴力加边再用Kruskal,边太多会超时。这里用一个算法来减少有效边的加入。

边权值为点间曼哈顿距离,那么每个点的有效加边选择应该是和他最近的4个象限方向的点。这里用一个树状数组维护以y-x为索引的y+x的值,然后这个数组所储存的就是一个点的第一象限方向的距离他最近的点。这样我们每次查找只要看(i,N)这个区间是否有一个点的距离比现在的更小(因为以y-x为索引,所以I>i就表示I这个点在i的第一象限方向)。最后每个方向的边都加完后,只要用Kruskal算法加边,加到第K就输出权值。

证明

详解

代码:

#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 10000+5;
const int INIT = 1061109567;
using namespace std;
int n,k,cnt,Id[N],v[N],f[N];//id为v值的id序号,v为储存以y-x为索引的y+x值 
struct node{
int x,y,id;
friend bool operator < (node a,node b){
return a.x == b.x? a.y < b.y : a.x < b.x;
}
}p[N];
struct edge{
int u,v,w;
friend bool operator < (edge a,edge b) {
return a.w < b.w;
}
}e[N<<2];
int lowbit(int x){
return x&(-x);
}
void query(int id,int pos,int val){
pos += 1000;
int u = -1,ret = INT_MAX;
for(int i = pos;i < N;i += lowbit(i)){
if(v[i] < ret && v[i] != INIT){ //找曼哈顿距离最短的
ret = v[i];
u = Id[i];
}
}
if(u != -1){ //找到这种点就加一个边
e[cnt].u = id;
e[cnt].v = u;
e[cnt++].w = ret - val;
}
}
void update(int id,int pos,int val){ //id,y-x,y+x
pos += 1000;
for(int i = pos;i > 0;i -= lowbit(i)){
if(val < v[i]){//更换最佳选择
v[i] = val;
Id[i] = id;
}
}
}
int find(int x){
if(x == f[x]) return x;
else return f[x] = find(f[x]);
}
void kruskal(){
sort(e,e+cnt);
for(int i = 0;i < N;i++) f[i] = i;
int num = n;
for(int i = 0;i < cnt;i++){
int x = find(e[i].u);
int y = find(e[i].v);
if(x != y){
f[x] = f[y];
num--;
if(num == k){
printf("%d\n",e[i].w);
return;
}
}
}
}
void addEdge(){
memset(v,63,sizeof(v)); //v == 1061109567
sort(p,p+n);
for(int i = n-1;i >= 0;i--){
int index = p[i].y - p[i].x;
int val = p[i].y + p[i].x;
query(p[i].id,index,val);
update(p[i].id,index,val);
}
}
int main(){
cnt = 0;
scanf("%d%d",&n,&k);
for(int i = 0;i < n ;i++){
scanf("%d%d",&p[i].x,&p[i].y);
p[i].id = i;
} addEdge(); for(int i = 0;i < n;i++) swap(p[i].x,p[i].y);
addEdge(); for(int i = 0;i < n;i++) p[i].y = -p[i].y;
addEdge(); for(int i = 0;i < n;i++) swap(p[i].x,p[i].y);
addEdge(); kruskal();
return 0;
}

POJ3241 Object Clustering(最小生成树)题解的更多相关文章

  1. POJ3241 Object Clustering 曼哈顿最小生成树

    题意:转换一下就是求曼哈顿最小生成树的第n-k条边 参考:莫涛大神的论文<平面点曼哈顿最小生成树> /* Problem: 3241 User: 96655 Memory: 920K Ti ...

  2. 【Poj3241】Object Clustering

    Position: http://poj.org/problem?id=3241 List Poj3241 Object Clustering List Description Knowledge S ...

  3. POJ 3241 Object Clustering 曼哈顿最小生成树

    Object Clustering   Description We have N (N ≤ 10000) objects, and wish to classify them into severa ...

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

    Object Clustering Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 2640   Accepted: 806 ...

  5. 【poj3241】 Object Clustering

    http://poj.org/problem?id=3241 (题目链接) MD被坑了,看到博客里面说莫队要写曼哈顿最小生成树,我就写了一个下午..结果根本没什么关系.不过还是把博客写了吧. 转自:h ...

  6. 【POJ 3241】Object Clustering 曼哈顿距离最小生成树

    http://poj.org/problem?id=3241 曼哈顿距离最小生成树模板题. 核心思想是把坐标系转3次,以及以横坐标为第一关键字,纵坐标为第二关键字排序后,从后往前扫.扫完一个点就把它插 ...

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

    先上几个资料: 百度文库有详细的分析和证明 cxlove的博客 TopCoder Algorithm Tutorials #include <cstdio> #include <cs ...

  8. POJ 3241 Object Clustering(Manhattan MST)

    题目链接:http://poj.org/problem?id=3241 Description We have N (N ≤ 10000) objects, and wish to classify ...

  9. 老oj3444 && Pku3241 Object Clustering

    Description We have N (N ≤ 10000) objects, and wish to classify them into several groups by judgemen ...

随机推荐

  1. Flip Game---poj1753(状压+bfs)

    题目链接:http://poj.org/problem?id=1753    题意:是有一个4X4的图,b代表黑色,w代表白色,问最少翻转几次可以把所有的点变成白色或者黑色,每次翻转一个点时,可以把它 ...

  2. pyqt5 主界面打开新主界面、打开Dialog、打开提示框的实现模板

    import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * ###### ...

  3. 从MySQL开发规范处看创业

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/n88Lpo/article/details/78099185 作者:唐勇.深圳市环球易购.MySQL ...

  4. HDU Today(自己的代码不知道哪里错了一直没A抄袭大神的)

    http://acm.hdu.edu.cn/showproblem.php?pid=2112 本题题目意思非常简单,麻烦的就是处理一下字符串,这是我能力欠缺的地方 ;} 先把我有乱有麻烦的错误代码贴上 ...

  5. zw版【转发·台湾nvp系列Delphi例程】HALCON SigmaImage1

    zw版[转发·台湾nvp系列Delphi例程]HALCON SigmaImage1 procedure TForm1.Button1Click(Sender: TObject);var img, im ...

  6. POJ3608

    计算两个凸包之间的最小距离,旋转卡壳法详解在旋转卡壳的用法之计算两个凸 包上的最近距离 #include <iostream> #include<cstdio> #includ ...

  7. 去除input的默认样式

    input, button, select, textarea { outline: none; -webkit-appearance: none; border-radius: 0; } outli ...

  8. python isinstance用法

    isinstance(object,type) 其第一个参数(object)为对象,第二个参数(type)为类型名(int...)或类型名的一个列表((int,list,float)是一个列表). 其 ...

  9. Java设计模式应用——过滤器模式

    storm引擎计算出一批中间告警结果,会发送一条kafka消息给告警入库服务,告警入库服务接收到kafka消息后读取中间告警文件,经过一系列处理后把最终告警存入mysql中. 实际上,中间告警结果可能 ...

  10. python 线程、多线程

    复习进程知识: python:主进程,至少有一个主线程 启动一个新的子进程:Process,pool 给每一个进程设定一下执行的任务:传一个函数+函数的参数 如果是进程池:map函数:传入一个任务函数 ...