一道不错的题,解法不少。
最易于理解的是最小生成树的做法:
首先每两个点之间都连一条长度为这两个点的距离的边,形成完全图。
然后跑最小生成树,直到剩k个联通块,这时候合并成k - 1个联通块的边的长度就是答案(注意,是连接两个联通块的边,否则就不是部落间的距离了)。
正确性很显然。因为这保证了部落内的距离尽量小,则部落外的距离尽量大,所以靠的最近的两个部落也就尽可能的远离。
还有一种二分答案的方法:
每一次把距离小于mid的点都划分成一个部落,最后看形成的部落总数和k的关系,如果小于k,向左二分;否则向右二分。
时间复杂度都是O(ElogE),E为边数,等于n * (n - 1) / 2。(最小生成树算法排序时间O(ElogE),跑kruskal时时O(E)的)
方法一的代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e3 + 5; 21 const int maxe = 5e5 + 5; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) {last = ch; ch = getchar();} 27 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, k; 39 struct Node 40 { 41 int x, y; 42 }a[maxn]; 43 struct Edge 44 { 45 int x, y; ll c; 46 bool operator < (const Edge &oth)const 47 { 48 return c < oth.c; 49 } 50 }e[maxe]; 51 int ecnt = 0; 52 53 ll calc(Node a, Node b) 54 { 55 return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); 56 } 57 58 int p[maxn]; 59 void init() 60 { 61 for(int i = 1; i <= n; ++i) p[i] = i; 62 } 63 int Find(int x) 64 { 65 return x == p[x] ? x : p[x] = Find(p[x]); 66 } 67 68 int main() 69 { 70 n = read(); k = read(); 71 init(); 72 for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(); 73 for(int i = 1; i < n; ++i) 74 for(int j = i + 1; j <= n; ++j) 75 e[++ecnt] = (Edge){i, j, calc(a[i], a[j])}; 76 sort(e + 1, e + ecnt + 1); 77 int cnt = n; 78 for(int i = 1; i <= ecnt; ++i) 79 { 80 int px = Find(e[i].x), py = Find(e[i].y); 81 if(px != py) 82 { 83 if(cnt-- == k) {printf("%.2lf ", sqrt(e[i].c)); return 0;} 84 p[px] = py; 85 } 86 } 87 return 0; 88 }