版权声明:欢迎大佬批评指正!O(∩_∩)O https://blog.csdn.net/wyh1618/article/details/82792502
3282: 向往的气球
题目描述
一年一度的计控ACM院赛即将来临。除了ACMers以外,志愿者们也非常的忙碌。他们需要将各种颜色的气球分配给A掉相应题目的队伍。现在,所有比赛队伍的成员都处在一个房间中,这个房间是一个二维坐标系,大小为1000行x1000列。
每一个坐标对应着空座位或某个参赛队伍。每一分钟,志愿者们都应该把所有的气球聚集在一起。志愿者将会被告知把气球送到哪里。为了保证工作的效率,对于两个坐标(x1,y1)和(x2,y2),如果|x1-x2|不大于k 或者 |y1-y2|不大于k,则这两个坐标的气球由同一个志愿者配送。你能知道最少需要多少志愿者,才能配送完所有的气球吗?
输入
第一行包含一个整数T,表示有T组数据。
对于每一组数组,这里将有n+1行
第一行:输入两个整数n,k; n表示气球的数量,k表示题目中的k值
接下来的n行中,每一行包含两个整数r,c。表示气球应该被送往r行,c列。请注意坐标可能会相同。
题目中保证:T<=100,1<=n<=10000,1<=k,r,c<=1000
输出
对于每一组数据,你需要输出一行
输出最少需要的志愿者数量
样例输入
2 3 5 1 1 10 6 15 20 2 5 1 1 7 7
样例输出
1 2
/*
题目要算最少需要几个志愿者,最直接的想法把满足条件的几个区域都归一个志愿者; 实在满足不了的就只能再找另一个志愿者++;
所以就要解决两个问题
1.如何把满足条件的坐标都合并在一起;
2.如果坐标都合并在一起了,如何查找坐标是不是一个集合里的呢?
-->>-->>并查集呗。。。。。
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
struct P
{
int r;
int c;
//int pRank;
} p[10010];
P parent[1010][1010];
bool cmp1(P a, P b)
{
return a.r<b.r;
}
bool cmp2(P a,P b)
{
return a.c<b.c;
}
P findRoot(P pp)
{
if(parent[pp.r][pp.c].r==pp.r&&parent[pp.r][pp.c].c==pp.c)
return pp;
else
return parent[pp.r][pp.c]=findRoot(parent[pp.r][pp.c]);
}
void unionNode(P p1,P p2)
{
P g1=findRoot(p1);
P g2=findRoot(p2);
if(g1.r==g2.r&&g1.c==g2.c)
{
return ;
}
//if(g1.pRank<g2.pRank)
parent[g1.r][g1.c]=g2;
/*else
{
parent[g2.r][g2.c]=g1;
if(g1.pRank==g2.pRank)
g1.pRank++;
}*/
}
int main()
{
int t,n,m,k,rr,cc;
cin>>t;
for(int i=0;i<t;i++)
{
memset(parent,0,sizeof(parent));
cin>>n>>k;
for(int i=0;i<n;i++)
{
cin>>rr>>cc;
p[i].r=rr;
p[i].c=cc;
//p[i].pRank=0;
parent[rr][cc].r=rr;
parent[rr][cc].c=cc;
}
sort(p,p+n,cmp1);
for(int i=0; i<n-1; i++)
{
if(p[i+1].r-p[i].r<=k)
{
unionNode(p[i],p[i+1]);
}
}
sort(p,p+n,cmp2);
for(int i=0;i<n-1;i++)
{
if(p[i+1].c-p[i].c<=k)
{
unionNode(p[i],p[i+1]);
}
}
int a=0;
for(int i=1;i<=1001;i++)
{
for(int j=1;j<=1001;j++)
{
if(parent[i][j].r==i&&parent[i][j].c==j)
a++;
}
}
cout<<a<<endl;
}
return 0;
}