HDU1875——畅通工程再续(最小生成树:Kruskal算法)

畅通工程再续

Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组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算法过的。

    这个题的顶点是用(x,y)存的,可以用结构体存。

    通过判断是否会有N-1条边加入树来判断是否可以生成最小树。

    PS:sqrt()里面要是INT型等整型,需要强制转换,因为math.h中有 double sqrt(double),float sqrt(flaot),long double sqrt(long double)三个函数。HDU会报编译错误。

Code:

 1 #include<stdio.h>
 2 #include<string>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<iostream>
 7 #define MAXN 5000
 8 using namespace std;
 9 struct point
10 {
11     int x,y;
12     int father;
13 } P[120];
14 struct edge
15 {
16     int begin;
17     int end;
18     double dis;
19 } T[MAXN+10];
20 void init()
21 {
22     for (int i=1; i<=MAXN; i++)
23         P[i].father=i;
24 }
25 int find(int x)
26 {
27     if (P[x].father!=x)
28         P[x].father=find(P[x].father);
29     return P[x].father;
30 }
31 void join(int x,int y)
32 {
33     int fx=find(x),fy=find(y);
34     if (fx!=fy)
35         P[fx].father=fy;
36 }
37 bool cmp(struct edge a,struct edge b)
38 {
39     return a.dis<b.dis;
40 }
41 double dis2(int x1,int y1,int x2,int y2)
42 {
43     return sqrt((double)((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
44 }
45 int main()
46 {
47     int S;
48     cin>>S;
49     while (S--)
50     {
51         init();
52         int C;
53         cin>>C;
54         for (int i=1; i<=C; i++)
55             cin>>P[i].x>>P[i].y;
56         int k=1;
57         bool ok=0;
58         for (int i=1; i<=C; i++)
59             for (int j=1; j<i; j++)
60             {
61                 T[k].dis=dis2(P[i].x,P[i].y,P[j].x,P[j].y);
62                 T[k].begin=i;
63                 T[k].end=j;
64                 k++;
65             }
66         sort(T+1,T+k,cmp);
67         int sum=0;
68         double cnt=0;
69 
70         for (int i=1; i<k; i++)
71         {
72             if (find(T[i].begin)!=find(T[i].end)&&
73                 (10.000000<=T[i].dis&&T[i].dis<=1000.000001))
74             {
75                 sum++;
76                 cnt+=T[i].dis;
77                 join(T[i].begin,T[i].end);
78             }
79             if (sum==C-1)
80             {
81                 ok=1;
82                 break;
83             }
84         }
85         if (ok) printf("%.1lf
",cnt*100);
86         else printf("oh!
");
87     }
88     return 0;
89 }
原文地址:https://www.cnblogs.com/Enumz/p/3855242.html