关闭

POJ 1838 Banana(并查集)

430人阅读 评论(0) 收藏 举报
分类:

Description
一个点用坐标(x,y)表示,如果两个点在水平方向或垂直方向上相邻,则两个点属于一个区域,即点1(x1,y1),点2(x2,y2)相邻当且仅当x1==x2,|y1-y2|=1或者|x1-x2|=1,y1=y2。给定一些点,相邻的点构成一个区域,求出k个区域所能拥有的最大点数(k不大于区域数)
Input
第一行两个整数n和k分别代表点数和区域数,之后n行为n个点的坐标
Output
输出k个区域所能拥有的最大点数
Sample Input
10 3
7 10
1 1
101 1
2 2
102 1
7 11
200 202
2 1
3 2
103 1
Sample Output
9
Solution
可用并查集解决,一个区域表示为一个并查集,两个区域相邻时,合并这两个并查集。同时记录并查集中的点数目。
初始时,每个点为一个并查集。对x坐标相同、y坐标相差为1的点,合并它们所在的并查集,合并时需要判断两个点是否位于同一个集合。合并时需要先找到各自集合的根节点,然后让其中一个根节点指向另一个根节点完成合并。对y坐标相同、x坐标相差为1的点,合并它们所在的并查集。
当所有相邻点进行了合并操作之后,对并查集点数目从大到小排序,取前K个值的总和作为结果输出。
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF (1<<29)
#define maxn 16005
struct node
{
    int x,y,flag;//x,y记录点坐标,flag记录点的下标便于操作 
}pos[maxn];
int par[maxn];
int rank[maxn];
int mem[maxn];
int ans[maxn];
int n,k,num;
void init(int n)
{
    for(int i=0;i<n;i++)
    {
        par[i]=i;
        rank[i]=0;
        mem[i]=1;
        pos[i].flag=i;
    }
}
int find(int x)
{
    if(par[x]==x)
        return x;
    return par[x]=find(par[x]);
}
void unite(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y)
        return ;
    if(rank[x]<rank[y])
    {
        par[x]=y;
        mem[y]+=mem[x];//合并区域点数相加 
    }
    else
    {
        par[y]=x;
        mem[x]+=mem[y];//合并区域点数相加 
        if(rank[x]==rank[y])
            rank[x]++;
    }
}
int cmp_x(node a,node b)
{
    if(a.x==b.x)
        return a.y<b.y;
    return a.x<b.x;
}
int cmp_y(node a,node b)
{
    if(a.y==b.y)
        return a.x<b.x;
    return a.y<b.y;
}
int cmp(int x,int y)
{
    return x>y;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%d%d",&pos[i].x,&pos[i].y);
    init(n);
    sort(pos,pos+n,cmp_x);//对点按横坐标升序排 
    for(int i=0;i<n-1;i++)//对x坐标相同、y坐标相差为1的点,合并它们所在的并查集
        if(pos[i].x==pos[i+1].x&&pos[i+1].y-pos[i].y==1)
            unite(pos[i].flag,pos[i+1].flag);
    sort(pos,pos+n,cmp_y);//对点按纵坐标升序排 
    for(int i=0;i<n-1;i++)//对y坐标相同、x坐标相差为1的点,合并它们所在的并查集 
        if(pos[i].y==pos[i+1].y&&pos[i+1].x-pos[i].x==1)
            unite(pos[i].flag,pos[i+1].flag);
    int res=0;
    for(int i=0;i<n;i++)//找到每个区域的根节点,记录该区域的点数 
        if(par[i]==i)
            ans[res++]=mem[i];
    sort(ans,ans+res,cmp);//对每个区域点数按降序排 
    for(int i=0;i<k;i++)//取前k个区域即为最大值 
        num+=ans[i];
    printf("%d\n",num);
    return 0;
}
0
0
查看评论

POJ 1838 Banana (并查集)

Description Consider a tropical forrest, represented as a matrix. The cell from the right top corner of the matrix has the coordinates (1,1), and t...
  • u013923947
  • u013923947
  • 2014-09-05 00:10
  • 916

POJ 1838 Banana(并查集)

题目: 一个点用坐标(x,y)表示,如果两个点在水平方向或垂直方向上相邻,则两个点属于一个区域,即点1(x1,y1),点2(x2,y2)相邻当且仅当x1==x2,|y1-y2|=1或者|x1-x2|=1,y1=y2。给定一些点,相邻的点构成一个区域,求出k个区域所能拥有的最大点数。(k不大于区域数...
  • lijiecsu
  • lijiecsu
  • 2012-04-22 22:06
  • 787

poj 1838 Banana

题意分析: 其实这道题蛮容易理解的,就是在平面上给你N个点,水平和垂直方向为相邻,这些相邻的点可以看成一个区域。现在可以连同k个区域,求在这k个区域内,点的个数尽量多。如果你对并查集和熟悉的话,你会发现其实这道题蛮容易的。因为并查集讲的就是动态连通性。 代码如下: #include #include...
  • lms1256012967
  • lms1256012967
  • 2014-12-15 00:26
  • 156

POJ 1838 Banana 笔记

Nr棵香蕉树,已知每棵香蕉树的坐标,上下左右相邻的香蕉树形成香蕉林,可连接K片香蕉林,求连接的香蕉林最多有多少棵香蕉树。
  • woniupengpeng
  • woniupengpeng
  • 2017-07-12 08:51
  • 73

POJ并查集的题目汇总

POJ1611 The suspects题目描述: 有很多组学生,在同一个组的学生经常会接触,也会有新的同学的加入。但是SARS是很容易传染的,只要在改组有一位同学感染SARS,那么该组的所有同学都被认为得了SARS。现在的任务是计算出有多少位学生感染SARS了。假定编号为0的同学是得了SAR...
  • u013244517
  • u013244517
  • 2015-01-13 17:20
  • 318

POJ并查集小结(转)

并查集小结 并查集大体分为三个:普通的并查集,带种类的并查集,扩展的并查集(主要是必须指定合并时的父子关系,或者统计一些数据,比如此集合内的元素数目。) POJ-1182 经典的种类并查集 POJ-1308 用并查集来判断一棵树。。注意空树也是树,死人也是人。 POJ-1611 ...
  • shahdza
  • shahdza
  • 2011-07-06 09:04
  • 6237

食物链 POJ1182 -- 并查集

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26553   Accepted: 7718 D...
  • tiantangrenjian
  • tiantangrenjian
  • 2011-12-19 21:06
  • 9273

【带偏移量的并查集】:poj***,Butterfly

输入 输入包含多组数据,以文件结束符为终止。 每组数据第一行为两个整数,分别是n和m: n为蝴蝶的数量,编号从0到n-1 m为关系的数量 接下来是m组关系数据,每组数据占一行,为三个整数,前两个整数表示蝴蝶的编号,第三个整数为关系的种类(相同或者不同): 0为相同,1为不同 1 1 输出 ...
  • mmc2015
  • mmc2015
  • 2015-12-02 22:07
  • 884

poj Supermarket(贪心)(并查集)(优先队列)

Supermarket Description A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that i...
  • blessLZH0108
  • blessLZH0108
  • 2017-03-08 21:48
  • 291

poj 1182 食物链(经典!种类并查集)

链接: http://poj.org/problem?id=1182 原题: Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。  现有N个动物,以1-N编号。每个动物都是A,B,C中的一...
  • shuangde800
  • shuangde800
  • 2012-09-24 00:10
  • 7328
    个人资料
    • 访问:555964次
    • 积分:24576
    • 等级:
    • 排名:第315名
    • 原创:1943篇
    • 转载:0篇
    • 译文:0篇
    • 评论:69条
    最新评论