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