Description
在平面直角坐标系内有n个点。现在有m个人,每个人都有一个行走距离d,也就是说这个人只能走到与它当前位置距离不大于d的点。问有多少个人可以从任意一个点开始,并能够到达所有点。
Input
第一行为一个整数m,表示人的个数。
第二行为m个整数d,表示每个人的行走距离。
第三行为一个数n,表示点的数量。
接下来n行每行包含两个整数x,y,表示平面内一个点的坐标。
Output
一行一个整数表示答案。
Sample Input
4
1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
Sample Output
3
Hint
对于40%的数据,2<=n<=100,1<=m<=100
对于100%的数据,2<=n<=1000,1<=m<=500,1<=d<=1000,-1000<=x,y<=1000
做法:最小生成树。。模板。。
代码如下:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#define maxn 2000007
using namespace std;
struct arr
{
int x,y;
double w;
}g[maxn];
int a[20007],q[20007],p[20007],n,m,f[20007],e,ans=0;
double mid=0.0;
int find(int x)
{
if (!f[x]) return x;
f[x]=find(f[x]);
return f[x];
}
double compare(arr a,arr b)
{
return a.w<b.w;
}
double pow2(double x,double y)
{
return x*x;
}
int main()
{
//freopen("jump.in","r",stdin);
//freopen("jump.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for (int i=1;i<=m;i++)
scanf("%d%d",&q[i],&p[i]);
for (int i=1;i<m;i++)
for (int j=i+1;j<=m;j++)
{
e++;
g[e].x=i;
g[e].y=j;
g[e].w=sqrt(pow2(q[i]-q[j],2)+pow2(p[i]-p[j],2));
}
sort(g+1,g+e+1,compare);
for (int i=1;i<=e;i++)
if (find(g[i].x)!=find(g[i].y))
{
f[find(g[i].x)]=find(g[i].y);
mid=g[i].w;
}
for (int i=1;i<=n;i++)
if (a[i]>=mid) ans++;
cout<<ans;
fclose(stdin);
fclose(stdout);
}