HDU4463 Outlets

  原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=4463

  这题算是比较裸的最小生成树。由于耐克店和苹果店要有公路相连,所以要先加上这条公路长度,然后将这条公路长度置0,那么就不会影响求最小生成树的贪心过程。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <math.h>
 5 const int maxn = 50 + 2;
 6 
 7 struct node 
 8 {
 9     double x, y;
10 }s[maxn];
11 int u[maxn*maxn], v[maxn*maxn], p[maxn*maxn], r[maxn*maxn], a, b, n, m;
12 double w[maxn*maxn];
13 
14 int cmp(const int i, const int j)
15 {return w[i] - w[j] < 1e-8;}
16  
17 int find(int x)
18 {return p[x] == x ? x : p[x] = find(p[x]);}
19 
20 double len(int i, int j)
21 {return sqrt((s[j].y - s[i].y) * (s[j].y - s[i].y) + (s[j].x - s[i].x) * (s[j].x - s[i].x));}
22 
23 double Kruskal()
24 {
25     double mst = 0;
26     mst += len(a-1, b-1);
27     for(int i = 0; i < n; i ++)
28         p[i] = i;
29     for(int i = 0; i < m; i ++)
30         r[i] = i;
31     std::sort(r, r + m, cmp);
32     for(int i = 0; i < m; i ++)
33     {
34         int e = r[i];
35         int x = find(u[e]);
36         int y = find(v[e]);
37         if(x != y)
38         {
39             mst += w[e];
40             p[x] = y;
41         }
42     }
43     return mst;
44 }
45 
46 int main()
47 {
48     while(scanf("%d", &n) == 1 && n)
49     {
50         scanf("%d%d", &a, &b);
51         if(a > b) std::swap(a, b);
52         for(int i = 0; i < n; i ++)
53             scanf("%lf%lf", &s[i].x, &s[i].y);
54         m = 0;
55         for(int i = 0; i < n; i ++)
56             for(int j = i + 1 ; j < n; j ++)
57                 u[m] = i, v[m] = j, w[m++] = (i == a-1 && j == b-1) ? 0.0 : len(i, j);
58         
59         printf("%.2f\n", Kruskal());
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/huangfeihome/p/2785124.html