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 ...
随机推荐
- Node.js高级编程读书笔记 - 5 数据库 - Never
Outline 6 连接数据库 6.1 使用node-mysql连接MySQL数据库 6.2 使用Nano连接CouchDB数据库 6.3 使用Mongoose连接MongoDB数据库 6 连接数据库 ...
- JavaBean用JSP调用和使用JSP动作标签的区别
javabean的类可以用jsp动作标签实例化并使用. <!-- 下面这句是对Javabean类person的引用,引用的实例是p2 --> <jsp:useBean id=&quo ...
- 一些上流的CSS3图片样式
直接在图片元素上直接应用CSS3 inset box-shadow 或 border-radius时,浏览器并不能完美的渲染它们.不过,如果把这个图片用作背景图,你就可以可以给它添加任何样式了,浏览器 ...
- Apache Shiro 使用手册(一)Shiro架构介绍
一.什么是Shiro Apache Shiro是一个强大易用的Java安全框架,提供了认证.授权.加密和会话管理等功能: 认证 - 用户身份识别,常被称为用户"登录": 授权 - ...
- codeforces 356 C. Compartments 构造 贪心
一辆车,有n个车厢,每个车厢刚好有4个人 车上有n个学生,第i个车厢有a[i]个学生 如果一个车厢里面的学生数 <= 2,这个车厢里的学生会不开心 如果一个车厢里面的学生数 > 2,这个车 ...
- FileUploadInterceptor拦截器的笔记
当请求表单中包含一个文件file,FileUploadInterception拦截器会自动应用于这个文件. 表单: <s:form namespace="/xxx" acti ...
- java io流(字符流) 文件打开、读取文件、关闭文件
java io流(字符流) 文件打开 读取文件 关闭文件 //打开文件 //读取文件内容 //关闭文件 import java.io.*; public class Index{ public sta ...
- PHP发送请求头和接收打印请求头
一.发送请求头 //发送地址 $url = 'http://127.0.0.1/2.php'; //请求头内容 $headers = array( 'Authorization: '.$basic, ...
- IOS跳转设置页面及其他各种跳转页面设置
转载来源 CocoaChina 跳到更多设置界面 除了跳到WiFi设置界面,能不能跳到其他的设置界面呢?比如:定位服务.FaceTime.音乐等等.都是可以的,一起来看看如何实现的! 定位服务 定位服 ...
- 为什么在注册和注销的时候intent要改成隐式调用
显式意图:调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件. 隐式意图: ...