poj3241 曼哈顿最小距离生成树第k大的边
思路:
已知:
要生成曼哈顿距离最小生成树,一个点最多和四周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大的边的更多相关文章
- POJ3241 最小曼哈顿距离生成树 - 真有趣哇
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog Problem:Portal传送门 原题目描述在最下面. 给你n个坐标, ...
- poj 2349 Arctic Network(最小生成树的第k大边证明)
题目链接: http://poj.org/problem?id=2349 题目大意: 有n个警戒部队,现在要把这n个警戒部队编入一个通信网络, 有两种方式链接警戒部队:1,用卫星信道可以链接无穷远的部 ...
- [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 ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- 区间第K大(一)
Problem: 给定无序序列S:[b, e),求S中第K大的元素. Solution 1.裸排序 2.现将区间均分成两段,S1, S2,对S1,S2分别排序,然后
- 寻找数组中的第K大的元素,多种解法以及分析
遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...
- [51nod1685]第k大区间
Description 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出$n$个数,求将所有长度为奇数的区间的值排序后,第$k$大的值为多少. Input 第一行两个数$n$和$k$. ...
- 数据结构2 静态区间第K大/第K小
给定数组$A[1...N]$, 区间$[L,R]$中第$K$大/小的数的指将$A[L...R]$中的数从大到小/从小到大排序后的第$K$个. "静态"指的是不带修改. 这个问题有多 ...
- POJ 2985 The k-th Largest Group(树状数组 并查集/查找第k大的数)
传送门 The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8690 Acce ...
随机推荐
- 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
腾讯优测是专业的android自动化测试平台,拥有上千款真机,彻底解决android碎片化问题! 这里我要说的不是闪光灯的硬件特征,也不是说底层驱动的原理,我只是跟大家聊一聊在项目中遇到的一些关于闪光 ...
- LeetCode() Ugly Number II 背下来!
一个别人,非常牛逼的思路,膜拜了!orz!!!! vector <int> results (1,1); int i = 0, j = 0, k = 0; while (results.s ...
- VISIBLE、INVISIBLE、GONE的区别
VISIBLE:设置控件可见 INVISIBLE:设置控件不可见 GONE:设置控件隐藏 而INVISIBLE和GONE的主要区别是:当控件visibility属性为INVISIBLE时,界面保留了v ...
- js call()和apply()
一.call()和apply(),实例如下: function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } a ...
- Amazon Web Services
- c#调用C++DLL参数对应
//c++:Byte(unsigned char) ---- c#:System.Byte //c++:SHORT(short) ---- ...
- 在 github 上获取源码
比如访问: https://github.com/alifellod/NWebGather 可以找到下面的源码获取方式. 在github开源项目的页面上可以找到上图的三个获取源码方式. 使用git的网 ...
- Newtonsoft.Json(Json.net)的基本用法
Newtonsoft.Json(Json.net)的基本用法 其它资料 JSON详解 添加引用: 使用NuGet,命令:install-package Newtonsoft.Json 实体类: pub ...
- Android九宫图(draw9patch)
左边和上边的线决定重复的区域: 右边和下边的线决定显示内容的区域:
- Java中的异常-Throwable-Error-Exception-RuntimeExcetpion-throw-throws-try catch
今天在做一个将String转换为Integer的功能时,发现Integer.parseInte()会抛出异常NumberFormatException. 函数Integer.parseInt(Stri ...