BZOJ传送门
最小瓶颈路,求一条路径,使得$u->v$路径上的最大边权最小。
可以知道,最小瓶颈路必在最小生成树上,所以用最小生成树求解
求出最小的最大边权后和每个猴子的距离比较即可
(PS: 之前还用dfs跑。。结果发现直接比较即可。。)
/*
Date: 04-03-17 10:27
bzoj 2429
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define ms(i,j) memset(i,j,sizeof i);
using namespace std;
const int MAXM = 500 + 5, MAXN = 1000 + 5;
struct edge
{
int u;
int v;
double w;
bool operator < (const edge &b) const
{
return w < b.w;
}
}e[MAXN*MAXN];
int en = 0;
void addE(int x, int y, double w)
{
en++;
e[en].u = x;
e[en].v = y;
e[en].w = w;
}
int fa[MAXN];
int find(int x) {return (fa[x]==x) ? (x) : (fa[x] = find(fa[x]));}
int m, n;
int h[MAXM];
int x[MAXN], y[MAXN];
int main()
{
scanf("%d", &m);
for (int i=1;i<=m;i++)
{
scanf("%d", &h[i]);
}
scanf("%d", &n);
for (int i=1;i<=n;i++)
{
scanf("%d%d", &x[i], &y[i]); fa[i] = i;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i!=j)
{
addE(i, j, sqrt( (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ) );
}
sort(e+1, e+1+en); int tot = 0; double maxe = 0;
for (int i=1;i<=en;i++)
{
int fx = find(e[i].u);
int fy = find(e[i].v);
if (fx==fy) continue;
fa[fx] = fy; tot++;
if (tot == n-1) {maxe = e[i].w; break;}
}
int ans = 0;
for (int i=1;i<=m;i++)
{
if (h[i]>=maxe) ans++;
}
printf("%d\n", ans);
return 0;
}