[洛谷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 }

 

posted @ 2019-01-26 22:48  AC-Evil  阅读(207)  评论(0编辑  收藏  举报