poj1838 并查集 抽象模型

题意:
一个点用坐标(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

思路:利用并查集求出每个区域(集合)的元素个数。然后排序,使前k个相加。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 16005
using namespace std;

int n, k;
int f[N];
int num[N];//记录当前元素所在集合的元素个数
int ans[N];

typedef struct note {
	int x, y, site;//记录横纵坐标和点的标号
}node;

node pos[N];

void init()
{
	for (int i = 1; i <= n; i++)
	{
		f[i] = i;
		pos[i].site = i;//初始化点的标号
		num[i] = 1;//初始化每个元素所在集合的元素个数
	}
}

int find(int x)
{
	return x == f[x] ? x : f[x] = find(f[x]);
}

void merge(int x, int y)
{
	int t1 = find(x), t2 = find(y);
	if (t1 != t2)
	{
		f[t2] = t1;//以左为尊
		num[t1] += num[t2];//t1所在元素的个数加上t2所在元素的个数
	}
}

int cmp_x(node a, node b)
{
	if (a.x == b.x)
		return a.y < b.y;
	else
		return a.x < b.x;
}

int cmp_y(node a, node b)
{
	if (a.y == b.y)
		return a.x < b.x;
	else
		return a.y < b.y;
}

int cmp(int x, int y)
{
	return x > y;
}

int main()
{
	scanf("%d%d", &n, &k);
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &pos[i].x, &pos[i].y);
	init();
	//下边合并集合
	sort(pos + 1, pos + n + 1, cmp_x);//按x升序排列,x相等时y升序排列
	for (int i = 1; i < n; i++)
	{
		if (pos[i].x == pos[i + 1].x && pos[i + 1].y - pos[i].y == 1)//满足集合合并
			merge(pos[i].site, pos[i + 1].site);
	}
	sort(pos + 1, pos + n + 1, cmp_y);
	for (int i = 1; i < n; i++)
	{
		if (pos[i].y == pos[i + 1].y && pos[i + 1].x - pos[i].x == 1)//满足集合合并
			merge(pos[i].site, pos[i + 1].site);
	}
	
	int cnt = 0;
	for (int i = 1; i <= n; i++)
	{
		if (f[i] == i)//集合的祖先代表元素
			ans[cnt++] = num[i];
	}
	sort(ans, ans + cnt, cmp);
	int sum = 0;
	for (int i = 0; i < k; i++)
		sum += ans[i];
	printf("%d\n", sum);
	return 0;
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值