思路:

已知:

要生成曼哈顿距离最小生成树,一个点最多和四周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. 2015GitWebRTC编译实录14

    libvpx 尝试用脚本编译了下,发现有问题,就偃旗息鼓,改用他自己的configure了,在网上找了下,Git上有个现成的,直接用,更好些. https://github.com/brion/VPX ...

  2. Unity Shader——Writing Surface Shaders(3)——Surface Shader Lighting Examples

    Surface Shader 光照例子 这里有一些自定义光照模型和Surface Shaders的例子.通常的Surface Shader例子在这里. 由于延迟光照在某些自定义的逐材质光照模型中表现得 ...

  3. Oracle查询索引碎片及数据表空间使用情况

    --检查索引碎片情况,只能对单个表进行分析. --需要注意块的大小.索引的pctfree的值的大小.rowid的长度的不同,根据不同的情况修改相应的值 select index_name, c.NMB ...

  4. java 集合的使用 (一)

    1.使用整型列表 List<int> lstInt=new List<int>(); 结果不对,报的错误是:Syntax error, insert "Dimensi ...

  5. KO+bootstrap 模态窗全选绑定

    HTML <div id="modalAreaID01"> <button type="button" class="btn btn ...

  6. Unity3D外包

    北京动点软件长年承接Unity3D(U3D外包)项目,我们制作各类型VR/AR游戏,虚拟现实,增强现实项目! 品质保证,售后完备. 联系请加QQ:372900288  电话:13911652504 我 ...

  7. Eclipse *下载

    简单了解,Eclipse是绿色软件,下载下来是个压缩包,只需要解压,加上jdk就可以运行了. 相比MyEclipse而言,它是免费的,后者是收费的.各有侧重吧 有很多人用Eclipse,也有很多人用M ...

  8. MVC:上传文件时限制文件类型

    之前写过一篇:MVC:上传文件 今天补充下一个功能:如何限制上传文件类型 文件类型可以在前段限制,但是太容易被绕过,最好还是在后端处理. 修改upload方法代码: [HttpPost] public ...

  9. FC 坦克大战 老巢铁墙

    老巢外围铁墙E2A9:AC 80 EFEF80:A5 10 85 45 A5 45 AC D2 E2 用十六进制编辑器打开坦克大战的游戏文件搜索A5 45 F0 25 A5 0B改为AC 80 EF ...

  10. flash 自定义右键功能

    使用过程可能遇到的问题: MouseEvent.RIGHT_CLICK TypeError: Error #2007: 参数 type 不能为空. 首先在项目中设置编译参数. 如果是as项目,则在项目 ...