思路:

已知:

要生成曼哈顿距离最小生成树,一个点最多和四周8个点连线,那8个点分别是将那个点四周360度平分成8个区间,每个区间里面和那个点曼哈顿距离最小的点,所以如果有n个点,那么最多有4n条边,然后就可以用kruskal算法去做。

 #include <iostream>    //poj3241 曼哈顿距离最小生成树第k大的边
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#define mid ((l+r)>>1)
using namespace std; int ent; int temp1,temp2,temp3; int fa[]; class Point
{
public:
int x,y,id;
} point[]; class Tree
{
public:
int index,current;
} tree[<<]; class Edge
{
public:
int s,t,dis;
} edge[]; bool cmp(Point a,Point b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
} bool cmp2(Edge a,Edge b)
{
return a.dis<b.dis;
} int get_ans(Point a)
{
return a.y-a.x+;
} int get_dis(int a,int b)
{
return point[b].x+point[b].y-point[a].x-point[a].y;
} void build(int l,int r,int n)
{
tree[n].index=INT_MAX;
if(l==r)
{
tree[n].current=l;
return;
}
build(l,mid,n<<);
build(mid+,r,n<<|);
} void update(int l,int r,int n,int current,int aim)
{
int ans=point[aim].x+point[aim].y;
if(ans<tree[n].index)
tree[n].index=ans;
if(l==r)
{
if(ans==tree[n].index)
tree[n].current=aim;
return;
}
if(mid<current)
update(mid+,r,n<<|,current,aim);
else update(l,mid,n<<,current,aim);
} void search(int l,int r,int n,int current,int aim)
{
if(l==r)
{
if(tree[n].index<temp1)
{
temp1=tree[n].index;
temp2=tree[n].current;
}
return;
}
if(mid<current)
search(mid+,r,n<<|,current,aim);
else if(l>=current)
{
if(tree[n<<].index<tree[n<<|].index)
search(l,mid,n<<,current,aim);
else search(mid+,r,n<<|,current,aim);
}
else
{
if(tree[n<<].index>=tree[n<<|].index)
search(mid+,r,n<<|,current,aim);
else
{
search(l,mid,n<<,current,aim);
search(mid+,r,n<<|,current,aim);
}
}
} int find(int x)
{
int temp=x;
while(x!=fa[x])
x=fa[x];
while(temp!=fa[temp])
{
temp=fa[temp];
fa[temp]=x;
}
return x;
} int pos[];
bool sign[];
int ans[]; int main()
{
int n,k;
while(cin>>n>>k)
{
int m=;
ent=;
memset(sign,false,sizeof(sign));
for(int i=; i<n; i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
point[i].id=i;
}
for(int tot=; tot<; tot++)
{
if(tot==)
{
for(int i=; i<n; i++)
point[i].y=-point[i].y;
}
if(tot==||tot==)
{
for(int i=; i<n; i++)
{
point[i].x=point[i].x+point[i].y;
point[i].y=point[i].x-point[i].y;
point[i].x=point[i].x-point[i].y;
}
}
for(int i=; i<n; i++)
{
int temp=get_ans(point[i]);
if(!sign[temp])
{
pos[m++]=temp;
sign[temp]=true;
}
}
sort(pos,pos+m);
for(int i=; i<m; i++)
{
ans[pos[i]]=i;
}
sort(point,point+n,cmp);
build(,m-,);
for(int i=n-; i>; i--)
{
update(,m-,,ans[get_ans(point[i])],i);
temp1=INT_MAX;
search(,m-,,ans[get_ans(point[i-])],i-);
if(temp1!=INT_MAX)
{
edge[ent].s=point[i-].id,edge[ent].t=point[temp2].id;
edge[ent++].dis=get_dis(i-,temp2);
}
}
}
sort(edge,edge+ent,cmp2);
for(int i=; i<=n; i++)
fa[i]=i;
int tot=;
for(int i=; i<ent; i++)
{
int x=find(edge[i].s);
int y=find(edge[i].t);
if(x==y)
continue;
else
{
fa[y]=x;
tot++;
}
if(tot==n-k)
{
cout<<edge[i].dis<<endl;
break;
}
}
}
return ;
}

poj3241 曼哈顿最小距离生成树第k大的边的更多相关文章

  1. POJ3241 最小曼哈顿距离生成树 - 真有趣哇

    目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门  原题目描述在最下面.  给你n个坐标, ...

  2. poj 2349 Arctic Network(最小生成树的第k大边证明)

    题目链接: http://poj.org/problem?id=2349 题目大意: 有n个警戒部队,现在要把这n个警戒部队编入一个通信网络, 有两种方式链接警戒部队:1,用卫星信道可以链接无穷远的部 ...

  3. [LeetCode] Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  4. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  5. 区间第K大(一)

    Problem: 给定无序序列S:[b, e),求S中第K大的元素. Solution 1.裸排序 2.现将区间均分成两段,S1, S2,对S1,S2分别排序,然后

  6. 寻找数组中的第K大的元素,多种解法以及分析

    遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...

  7. [51nod1685]第k大区间

    Description 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出$n$个数,求将所有长度为奇数的区间的值排序后,第$k$大的值为多少. Input 第一行两个数$n$和$k$. ...

  8. 数据结构2 静态区间第K大/第K小

    给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...

  9. POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)

    传送门 The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8690   Acce ...

随机推荐

  1. Nginx 502 Bad Gateway 错误的原因及解决方法

    http://my.oschina.net/zhouyuan/blog/118708 刚才在调试程序的时候,居然服务器502错误,昨天晚上也发生了,好像我没有做非常规的操作. 然后网上寻找了下答案, ...

  2. github 如何合并不同分支

    From: http://stackoverflow.com/questions/1123344/merging-between-forks-in-github 1. 添加remote origina ...

  3. JSBinding+SharpKit / 菜单介绍

  4. GridView与CheckBox完美结合

    版本一:单纯地实现全选和全取消,http://www.cnblogs.com/insus/archive/2009/03/14/1411613.html 版本二:修改选中行的背景颜色,http://w ...

  5. ecstore与淘宝sdk的autoload加载顺序问题

    ecstore使用spl_autoload_register实现类的自动加载,这个很大的方便我们不用每次都要手动的去include一些类和函数.不过这样会导致一些问题,比如说,有一些extension ...

  6. 21副GIF动图让你了解各种数学概念

    baidu 21副GIF动图让你了解各种数学概念

  7. 认识angualrJS的resource服务

    这段时间公司有个项目要用到angularJS,于是就在网上开始各种找学习资料. 一开始下了一本<angularJS权威教程>,看了10章,实在看不下去了,只能说这本书对于才接触javasc ...

  8. 短作业优先调度算法(SJF)

    假设有n项作业位于就绪队列中,这些作业的提交时间用数组requestTimes按照提交时间的先后顺序存储,对应的作业服务时间(持续时间)用数组durations存储.采用SJF算法,计算n项作业的平均 ...

  9. elasticsearch知识点

    1.分析:数据转化的过程. 两个转化过程-----传入文档中的数据转化程倒排序索引 -----查询文本转化成可被搜索的词 2.分析器:承担分析(数据转化)的工作 组成:一个分词器(tokenizer) ...

  10. IDEA新建javaWeb以及Servlet简单实现

    刚开始用IDEA开发,还不太熟悉,因此写一个教程,加深印象 1.新建一个Web项目 两种方法:java 和 Java Enterprise(推荐) 第一种)通过Java工程创建,这个方法需要手动导入T ...