题解 P2504 【[HAOI2006]聪明的猴子】

这道题要坑死人啊。。。

第一次做40分,其他RE,改了一次之后就变成20分了。。。

究其原因,是有一个数组(dis)开的太小了,于是最后本蒟蒻就随手开了个五百万,然后,就AC了

看到有一篇题解说求距离最好不开根,经本蒟蒻实验,开不开根并不影响结果,全看个人喜好。

本蒟蒻还加了一个快读,其实也没有必要,只是第一次RE的时候不小心看成了TLE,为了缩短时间才写的。

总体来说,这是一道Kruskal的题废话

需要注意的一个点在于题目所求的与裸题有差异。

其余的好像问题也不大,只要不像本蒟蒻一样视力不好就不会错得太离谱。

总而言之,AC代码如下(并查集find函数带优化):

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 inline int qread() {
 8     int x = 0, f = 1;
 9     char c = getchar();
10     while(c < '0' || c > '9') {
11         if(c == '-') f = -1;
12         c = getchar();
13     }
14     while(c >= '0' && c <= '9') {
15         x = x * 10 + (c - '0');
16         c = getchar();
17     }
18     return x * f;
19 }
20 
21 const int maxn = 1010;
22 
23 int m, n, ans = 0, cnt = 0;
24 int f[maxn], leap[maxn], x[maxn], y[maxn];
25 
26 struct node {
27     int x, y;
28     int val;
29 }dis[5000005];
30 
31 bool cmp(node a, node b) {
32     return a.val < b.val;
33 }
34 
35 int find(int x) {
36     int r = x;
37     while(r != f[r]) r = f[r];
38     int i = x, j;
39     while(f[i] != r) {  
40         j = f[i];  
41         f[i] = r;  
42         i = j;  
43     }
44     return r;  
45 }
46 
47 void merge(int x, int y) {
48     x = find(x);
49     y = find(y);
50     if(x != y) f[y] = x;
51 }
52 
53 double dt(int x1,int x2,int y1,int y2) {
54     return sqrt(pow(double(x1 - x2), 2) + pow(double(y1 - y2), 2));
55 }
56 
57 int main() {
58     cin >> m;
59     for(int i = 1; i <= m; i++) cin >> leap[i];
60     cin >> n;
61     for(int i = 1; i <= n; i++) cin >> x[i] >> y[i];
62     for(int i = 1; i <= maxn - 1; i++) f[i] = i;
63     
64     for(int i = 1; i <= n; i++) 
65         for(int j = i + 1; j <= n; j++) {
66             dis[++cnt].x = i;
67             dis[cnt].y = j;
68             dis[cnt].val = dt(x[i], x[j], y[i], y[j]);
69         }
70             
71             
72     sort(dis + 1, dis + cnt + 1, cmp);
73     for(int i = 1; i <= cnt; i++)
74         if(find(dis[i].x) != find(dis[i].y)) {
75             ans = dis[i].val;
76             merge(dis[i].x, dis[i].y);
77         }
78         
79     int sum = 0;
80     for(int i = 1; i <= m; i++) if(leap[i] >= ans) sum++;
81     
82     cout << sum;
83 }
原文地址:https://www.cnblogs.com/ilverene/p/9818973.html