题目描述
一年一度的计控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
距离合适的可以都交给一个人送,依据距离条件可以划分成若干集合。
并查集可以做到。
http://202.194.119.110/problem.php?id=3282
错误代码// 按照Y排序后序号会变,还傻傻看了一个下午,充分证明我是超级菜。
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
int x;
int y;
int vis;
}dian;
dian d[100005];
int f[100005];
bool cmp1(dian a,dian b)
{
return a.x<b.x;
}
bool cmp2(dian a,dian b)
{
return a.y<b.y;
}
int getf(int a)
{
return f[a]==a?a:f[a]=getf(f[a]);
}
void marge(int a,int b)
{
int aa,bb;
aa=getf(a);
bb=getf(b);
if(aa!=bb)
f[bb]=aa;
}
int main()
{
int t,n,k;
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>d[i].x>>d[i].y;
d[i].vis=i;
f[i]=i;
}
sort(d+1,d+1+n,cmp1);
for(int i=2;i<=n;i++)
{
if(d[i].x-d[i-1].x<=k)
marge(i-1,i); //要合并的是排完序后的序号
}
// for(int i=1;i<=n;i++)
// cout<<i<<"***"<<f[i]<<endl;
sort(d+1,d+1+n,cmp2);
for(int i=2;i<=n;i++)
{
if(d[i].y-d[i-1].y<=k)
marge(i-1,i); //要合并的是排完序后的序号,第二次排序后与第一次序号不同了
//不能仅仅依靠数组下标来划分集合
}
// for(int i=1;i<=n;i++)
// cout<<i<<"***"<<f[i]<<endl;
//
int sum=0;
for(int i=1;i<=n;i++)
{
if(f[i]==i)
sum++;
//cout<<i<<"***"<<f[i]<<endl;
}
cout<<sum<<endl;
}
return 0;
}
正确的代码
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
int x;
int y;
int vis;
}dian;
dian d[100005];
int f[100005];
bool cmp1(dian a,dian b)
{
return a.x<b.x;
}
bool cmp2(dian a,dian b)
{
return a.y<b.y;
}
int getf(int a)
{
if(a==f[a])
return a;
else
{
return f[a]=getf(f[a]);
}
//return f[a]==a?a:f[a]=getf(f[a]);
}
void marge(int a,int b)
{
int aa,bb;
aa=getf(d[a].vis);//不能仅仅依靠数组下标来划分集合
bb=getf(d[b].vis);//他原来是几号就搜几号
if(aa!=bb)
f[bb]=aa;
}
int main()
{
int t,n,k;
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>d[i].x>>d[i].y;
d[i].vis=i; //保存 唯一的身份
f[i]=i;
}
sort(d+1,d+1+n,cmp1);
for(int i=2;i<=n;i++)
{
if(d[i].x-d[i-1].x<=k)
marge(i-1,i);
}
// for(int i=1;i<=n;i++)
// cout<<i<<"***"<<f[i]<<endl;
sort(d+1,d+1+n,cmp2);
for(int i=2;i<=n;i++)
{
if(d[i].y-d[i-1].y<=k)
marge(i-1,i);
}
// for(int i=1;i<=n;i++)
// cout<<i<<"***"<<f[i]<<endl;
int sum=0;
for(int i=1;i<=n;i++)
{
if(f[i]==i)
sum++;
// cout<<i<<"***"<<f[i]<<endl;
}
cout<<sum<<endl;
}
return 0;
}