问题描述
在平面直角坐标系内有n个点。现在有m个人,每个人都有一个行走距离d,也就是说这个人只能走到与它当前位置距离不大于d的点。问有多少个人可以从任意一个点开始,并能够到达所有点。
输入
第一行为一个整数m,表示人的个数。
第二行为m个整数d,表示每个人的行走距离。
第三行为一个数n,表示点的数量。
接下来n行每行包含两个整数x,y,表示平面内一个点的坐标。
输出
一行一个整数表示答案。
样例输入
4
1 2 3 4
6
0 0
1 0
1 2
-1 -1
-2 0
2 2
样例输出
3
算法讨论
最小生成树,找到数中最大的边,可走步数大于等于这条边的人都可以走。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 1005
#define maxm 505
int b[maxm],a[maxn][2];
bool v[maxn];
double f[maxn][maxn],d[maxn];
int n,m,minn,t,maxx;
double sqr(int x)
{
return (x*x);
}
int main()
{
scanf("%d",&m);
for (int i=1;i<=m;i++)
scanf("%d",&b[i]);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d",&a[i][1],&a[i][2]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
f[i][j]=sqrt(sqr(a[i][1]-a[j][1])+sqr(a[i][2]-a[j][2]));
for (int i=1;i<=n;i++)
d[i]=f[1][i];
v[1]=1;
for (int i=1;i<n;i++)
{
minn=2147483647;
for (int j=1;j<=n;j++)
if (d[j]<minn && !v[j])
{
t=j;
minn=d[j];
}
if (minn>maxx)
maxx=minn;
v[t]=1;
for (int j=1;j<=n;j++)
if (f[t][j]<d[j])
d[j]=f[t][j];
}
sort(b+1,b+m+1);
t=0;
for (int i=m;i>=1;i--)
if (b[i]>maxx)
t++;
printf("%d",t);
return 0;
}
Pixiv ID:62552118