• POJ 1838 Banana 并查集


     题意:有一只猴子喜欢吃香蕉,但他只能在相邻的两棵香蕉树之间行动,如果两棵树是在横方向或竖方向相邻的,那么这就组成一个区域,这个区域内猴子可以随意走动,有人可以把k个区域连接起来,从而使猴子在这k个区域内随意行动,问猴子最多可以在多少棵树内走动?给定n个树的坐标,和k。

     思路不难,使用并查集来对这n个点进行操作,最后选出前k个最大的根节点相加即可。在并查集中pre[]是一个节点的所有子结点的个数,是一个负值。

    #include <iostream>
    #include
    <cstdio>
    #include
    <memory.h>
    #include
    <algorithm>
    using namespace std;

    #define MAXN 20000
    struct Node{
    int x,y;
    int num;
    }node[MAXN];
    bool cmp(const Node& a, const Node& b)
    {
    if(a.x == b.x) return a.y<b.y;
    return a.x<b.x;
    }
    bool cmp1(const Node& a,const Node& b)
    {
    if(a.y == b.y) return a.x<b.x;
    return a.y < b.y;
    }
    bool cmp2(const int& a,const int& b)
    {
    return a<b;
    }
    int pre[MAXN];
    int find_set( int x)
    {
    int root = x;
    int tmp;
    while(pre[root]>=0)
    root
    = pre[root];
    while(x!=root)
    {
    tmp
    = pre[x];
    pre[x]
    = root;
    x
    = tmp;
    }
    return root;
    }
    void union_set(const int& root1,const int& root2)
    {
    int a = pre[root1];
    int b = pre[root2];
    if(a > b)
    {
    pre[root1]
    = root2;
    pre[root2]
    = a+b;
    }
    else
    {
    pre[root2]
    = root1;
    pre[root1]
    = a+b;
    }
    }
    int main()
    {
    int n,m,i,j,k;
    int root1,root2;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
    memset(pre,
    -1,sizeof(pre));
    for(i = 0;i < n; ++i)
    {
    scanf(
    "%d%d",&node[i].x,&node[i].y);
    node[i].num
    = i;
    }
    sort(node,node
    +n,cmp);
    for(i = 0;i < n-1; ++i)
    if(node[i].x == node[i+1].x && node[i+1].y-node[i].y==1)
    {
    root1
    = find_set(node[i].num);
    root2
    = find_set(node[i+1].num);
    if(root1 != root2)
    union_set(root1,root2);
    }
    sort(node,node
    +n,cmp1);
    for(i = 0;i < n-1; ++i)
    if(node[i].y == node[i+1].y && node[i+1].x-node[i].x==1)
    {
    root1
    = find_set(node[i].num);
    root2
    = find_set(node[i+1].num);
    if(root1 != root2)
    union_set(root1,root2);
    }
    sort(pre,pre
    +n,cmp2);
    int ans = 0;
    for(i = 0; i < k;++i)
    ans
    -= pre[i];
    printf(
    "%d\n",ans);
    }
    return 0;
    }

  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1681909.html
Copyright © 2020-2023  润新知