原题传送: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 }