畅通工程再续
题目:畅通工程再续。
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。 Input 输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。 每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。 Output 每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”. Sample Input 2 2 10 10 20 20 3 1 1 2 2 1000 1000 Sample Output 1414.2 oh!
我们读完题以后会发现这就是一个求最小生成树的问题,需要利用kruskal算法。经过此题就可以很好的熟悉此算法。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 int f[100100]; 7 int find(int x) 8 { 9 if (x == f[x]) 10 return x; 11 else 12 return find(f[x]); 13 } 14 struct position 15 { 16 17 int x; 18 int y; 19 int nol; 20 } q[100100]; 21 struct road 22 { 23 struct position u; 24 struct position v; 25 double dis; 26 } p[100100]; 27 28 bool cmp1(road a, road b) 29 { 30 return a.dis < b.dis; 31 } 32 int main() 33 { 34 int n; 35 cin >> n; 36 while (n--) 37 { 38 int m; 39 cin >> m; 40 int i; 41 for (i = 1; i <= m; i++) 42 { 43 cin >> q[i].x >> q[i].y; 44 q[i].nol = i; 45 } 46 int k = 0; 47 int j; 48 for (i = 1; i <= m; i++) 49 { 50 for (j = i + 1; j <= m; j++) 51 { 52 k++; 53 p[k].u = {q[i].x, q[i].y, q[i].nol}; 54 p[k].v = {q[j].x, q[j].y, q[j].nol}; 55 p[k].dis = (q[i].x - q[j].x) * (q[i].x - q[j].x) + (q[i].y - q[j].y) * (q[i].y - q[j].y); 56 } 57 } 58 int w = m * (m - 1); 59 w = w / 2; 60 sort(p + 1, p + 1 + w, cmp1); 61 for (i = 1; i <= m; i++) 62 f[i] = i; 63 int ans = 1; 64 double res = 0; 65 for (i = 1; i <= w; i++) 66 { 67 if (find(p[i].u.nol) != find(p[i].v.nol) && p[i].dis >= 100 && p[i].dis <= 1000000) 68 { 69 f[find(p[i].u.nol)] = p[i].v.nol; 70 ans++; 71 res += 100 * (sqrt((double)p[i].dis)); 72 } 73 if (ans == m) 74 { 75 printf("%.1lf\n", res); 76 break; 77 } 78 } 79 if (ans < m) 80 printf("oh!\n"); 81 } 82 return 0; 83 }
第一次写,出了好多bug,写了一个多小时。。。,继续加油!

浙公网安备 33010602011771号