[洛谷P1991]无线通讯网
题目传送门
题意不难理解,实质就是最小生成树(MST),板子题,这里用的是$Kruskal$。$Prim$做法参考P1265。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define maxx(a, b) a = max(a, b); 9 #define minn(a, b) a = min(a, b); 10 #define LL long long 11 #define inf (1 << 30) 12 13 inline int read() { 14 int w = 0, f = 1; char c = getchar(); 15 while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar(); 16 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar(); 17 return w * f; 18 } 19 20 const int maxn = 500 + 5; 21 22 #define sqr(x) ((x) * (x)) 23 24 struct Edge { 25 int u, v; 26 double w; 27 } e[maxn * maxn]; 28 bool cmp(Edge a, Edge b) { return a.w < b.w; } 29 30 int f[maxn]; 31 int fset(int x) { return f[x] == x ? x : f[x] = fset(f[x]); } 32 void merge(int x, int y) { f[fset(x)] = fset(y); } 33 34 int n, x[maxn], y[maxn], m; 35 36 int main() { 37 m = read(), n = read(); 38 39 rep(i, 1, n) x[i] = read(), y[i] = read(); 40 41 rep(i, 1, n) 42 rep(j, 1, n) 43 e[i*n+j-n] = (Edge){i, j, sqrt(sqr(x[i]-x[j]) + sqr(y[i]-y[j]))}; 44 45 sort(e+1, e+n*n+1, cmp); 46 47 int p = 1; 48 rep(i, 1, n) f[i] = i; 49 50 while (n-- > m) { 51 while (fset(e[p].u) == fset(e[p].v)) p++; 52 merge(e[p].u, e[p].v); 53 } 54 55 printf("%.2lf", e[p].w); 56 57 return 0; 58 }