poj 1838 Banana

题意分析:

其实这道题蛮容易理解的,就是在平面上给你N个点,水平和垂直方向为相邻,这些相邻的点可以看成一个区域。现在可以连同k个区域,求在这k个区域内,点的个数尽量多。如果你对并查集和熟悉的话,你会发现其实这道题蛮容易的。因为并查集讲的就是动态连通性。

代码如下:


#include<iostream>
#include<cstdio>
#include<algorithm>


using namespace std;
struct node{
<span style="white-space:pre">	</span>int x,y,index;
} s[16010];
int pa[16010],flag[16010],result[16010],rank[16010];
int cmp(node a,node b) {
<span style="white-space:pre">	</span>if(a.x<b.x) return 1;
<span style="white-space:pre">	</span>else if(a.x==b.x && a.y < b.y)  return 1;
<span style="white-space:pre">	</span>return 0;
}
int cmpy(node a,node b) {
<span style="white-space:pre">	</span>if(a.y<b.y) return 1;
<span style="white-space:pre">	</span>else if(a.y==b.y && a.x < b.x)  return 1;
<span style="white-space:pre">	</span>return 0;
}
int cmp1(int a,int b) {
<span style="white-space:pre">	</span>return a>b;
}
int findset(int x) {
<span style="white-space:pre">	</span>return (x==pa[x]) ? x : (pa[x] = findset(pa[x]));
}


void unionset(int x,int y) {
<span style="white-space:pre">	</span>int a=findset(x),b=findset(y);
<span style="white-space:pre">	</span>if(a==b) return ;
<span style="white-space:pre">	</span>if(rank[a] < rank[b]) {
<span style="white-space:pre">		</span>pa[a] = b;
<span style="white-space:pre">		</span>flag[b]+=flag[a];
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else {
<span style="white-space:pre">		</span>if(rank[a] == rank[b]) rank[a]++;
<span style="white-space:pre">		</span>pa[b] = a;
<span style="white-space:pre">		</span>flag[a]+=flag[b];
<span style="white-space:pre">	</span>}
}
int main() {
<span style="white-space:pre">	</span>int n,k,i,j,sum=0;
<span style="white-space:pre">	</span>scanf("%d%d",&n,&k);
<span style="white-space:pre">	</span>for(i=0;i<n; i++) {
<span style="white-space:pre">		</span>scanf("%d%d",&s[i].x,&s[i].y);
<span style="white-space:pre">		</span>s[i].index = i;
<span style="white-space:pre">		</span>rank[i] = 0;
<span style="white-space:pre">		</span>pa[i] = i;
<span style="white-space:pre">		</span>flag[i]=1;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>sort(s,s+n,cmp);
<span style="white-space:pre">	</span>for(i=0; i<n-1; i++) {
<span style="white-space:pre">			</span>if(s[i+1].y-s[i].y==1 && s[i+1].x==s[i].x) {
<span style="white-space:pre">				</span>unionset(s[i].index,s[i+1].index);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>sort(s,s+n,cmpy);
<span style="white-space:pre">	</span>for(i=0; i<n-1; i++) {
<span style="white-space:pre">			</span>if(s[i+1].x-s[i].x==1 && s[i+1].y==s[i].y) {
<span style="white-space:pre">				</span>unionset(s[i].index,s[i+1].index);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>j=0;
<span style="white-space:pre">	</span>for(i=0; i<n; i++) {
<span style="white-space:pre">		</span>if(pa[i] == i) result[j++] = flag[i];
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>sort(result,result+j,cmp1);
<span style="white-space:pre">	</span>for(i=0; i<k; i++) sum+=result[i];
<span style="white-space:pre">	</span>cout<<sum<<endl;
<span style="white-space:pre">	</span>return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值