poj 1838 Banana(并查集)

http://poj.org/problem?id=1838

题意:有一个直角坐标系,相邻的点可以相连成一块,而且可以将k块相连,求最多有几个点可以连成一块。

思路:先并查集,再排序即可

 


#include<stdio.h>

#include<string.h>

#include<math.h>

#include<iostream>

#include<algorithm>

#include<queue>

#include<stack>

#define mem(a,b) memset(a,b,sizeof(a))

#define ll __int64

#define MAXN 16000

#define INF 0x7ffffff

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

struct Point

{

    int x,y;

    int id;

};

Point p[16000+10];

int  fa[16000+10];

int num[16000+10];

int cnt[16000+10];

int n;

int cmpx(Point a,Point b)

{

    if(a.x!=b.x) return a.x<b.x;

    return a.y<b.y;

}

int cmpy(Point a,Point b)

{

    if(a.y!=b.y) return a.y<b.y;

    return a.x<b.x;

}

int find(int a)

{

    if(fa[a]!=a) fa[a]=find(fa[a]);

    return fa[a];

}



void bincha(int a,int b)

{

    int x=find(a);

    int y=find(b);

    if(x==y) return ;

    fa[x]=fa[y];

    cnt[y]+=cnt[x];

    cnt[x]=0;

}

int main()

{

    int m;

    int i,j;

    while(cin>>n>>m)

    {



        for(i=1;i<=n;i++)

        {

            cnt[i]=1;

            fa[i]=p[i].id=i;

            scanf("%d%d",&p[i].x,&p[i].y);

        }

        sort(p+1,p+n+1,cmpx);

        for(i=1;i<n;i++)

        {

            if(p[i].x==p[i+1].x&&p[i+1].y-p[i].y==1&&fa[p[i+1].id]!=fa[p[i].id])

            {

               int pre=fa[p[i].id];

               int pre1=fa[p[i+1].id];

               fa[p[i+1].id]=fa[p[i].id];

               cnt[pre]+=cnt[pre1];

               cnt[pre1]=0;

            }

        }

        sort(p+1,p+n+1,cmpy);

        for(i=1;i<n;i++)

        {

            if(p[i].y==p[i+1].y&&p[i+1].x-p[i].x==1&&fa[p[i+1].id]!=fa[p[i].id])

            {

               bincha(p[i+1].id,p[i].id);

            }



        }

        j=0;

        for(i=1;i<=n;i++)

        {

            if(cnt[i]!=0)

            {

                num[j++]=cnt[i];

            }

        }

        sort(num,num+j);        

        j--;

        int ans=0;

        while(m--)

        {

            ans+=num[j--];

        }

        cout<<ans<<endl;

    }

    return 0;

}

  

你可能感兴趣的:(poj)