【bzoj1821】[JSOI2010]Group 部落划分 Group
题目大意:要求把n个点分成m块,使得每一块之间的距离的最小值最大
n^2枚举所有点之间距离
然后sort一下
并查集维护连通关系
一开始e[]开MAXN然后WA了测了4ms,然后开MAXN<<2又WA不过测了24ms,再开MAXN<<5又WA测了68ms
,又开MAXN<<10 TLE了= =,最后MAXN<<8过了。。。(是不是很无聊??)
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define MAXN 10010 struct Node { int x,y; double z; }e[MAXN<<8]; int k; int n,m; int ans; int x[MAXN],y[MAXN]; int f[MAXN]; int cmp(Node a,Node b) { return a.z<b.z; } double work(int a,int b) { int r1=x[a]-x[b]; int r2=y[a]-y[b]; return sqrt(r1*r1+r2*r2); } int find(int x) { return f[x]==x ? x : f[x]=find(f[x]); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) f[i]=i; for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for (int i=1;i<n;i++) for (int j=i+1;j<=n;j++) { k++; e[k].x=i; e[k].y=j; e[k].z=work(i,j); } sort(e+1,e+k+1,cmp); for (int i=1;i<=k;i++) { int r1=find(e[i].x); int r2=find(e[i].y); if (r1==r2) continue; if (n==m) { printf("%.2lf\n",e[i].z); break; } if (r1>r2) swap(r1,r2); f[r1]=r2; n--; } return 0; }