畅通工程再续

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19066    Accepted Submission(s): 5951


Problem 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!
 

 

Author
8600
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  1879 1102 1301 1162 3371 
//最小生成树两种方法: cool~、  最重要的是转化思想; 数据类型要对应 + 注意限制条件;
//Kruskal算法
 1 #include <cmath>
 2 #include <cstdio>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 110;
 8 double x[N], y[N];
 9 int father[N];
10 int i, j, k, n;
11 
12 struct node
13 {
14     int lano, lant; double dy;
15 } boy[N*N];
16 
17 bool cmp(node lano, node lant)
18 {
19     return lano.dy < lant.dy; 
20 } 
21 
22 int find(int a)
23 {
24     while(a != father[a])
25         a = father[a];
26     return a;     
27 }
28 
29 void mercy(int a, int b)
30 {
31     int q = find(a);
32     int p = find(b);
33     if(q != p)
34     father[q] = p;  
35 }
36 
37 int main()
38 {
39     int t;
40     scanf("%d", &t);
41     while(t--)
42     {
43         int n;
44         scanf("%d", &n);
45         double sum =0.0;
46         for(i=1; i<=n; i++){
47             father[i] = i;
48             scanf("%lf %lf", &x[i], &y[i]);
49         }
50         for(k=0, i=1; i<=n; i++)
51             for(j=1; j<=n; j++){
52                 double temp = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
53                 if(temp>=10 && temp<=1000)    //限制条件不要漏。
54                 {boy[k].lano = i, boy[k].lant =j, boy[k].dy = temp; k++;}
55             }
56         sort(boy, boy+k, cmp);
57         for(i=0; i<k; i++)
58         {
59             if(find(boy[i].lano) != find(boy[i].lant))
60             {
61                 mercy(boy[i].lano, boy[i].lant) ; 
62                 sum += boy[i].dy;
63             }
64         }
65         int total = 0;
66         for(i=1; i<=n; i++)
67         {
68             if(father[i] == i)
69             total++;
70             if(total > 2)
71             break;
72         }
73         if(total > 2)
74         printf("oh!\n");
75         else
76         printf("%.1lf\n", sum*100);
77     }
78     return 0;
79 } 

//prim算法:

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 using namespace std;
 6 
 7 const int N = 110;
 8 const int INF = 0x3f3f3f3f;
 9 
10 double map[N][N], x[N], y[N], dis[N], vis[N];
11 int i, j, k, n;
12 
13 void prim()
14 {
15     double sum=0.0;
16     memset(vis, 0, sizeof(vis));
17     for(i=1; i<=n; i++)
18     dis[i] = map[1][i];
19     vis[1] = 1;
20     for(i=1; i<n; i++)
21     {
22         double min = INF; int temp;
23         for(j=1; j<=n; j++)
24         {
25             if(!vis[j] && dis[j] < min)
26             {
27                 min = dis[j];
28                 temp = j;
29                 }    
30         }
31         if(min == INF)
32         {
33             printf("oh!\n");
34             return ;
35         }
36         vis[temp] = 1;
37         sum += min;
38         for(j=1; j<=n; j++)
39             if(!vis[j] && map[temp][j] < dis[j])
40                 dis[j] = map[temp][j];
41     }
42     printf("%.1lf\n", sum*100);
43 }
44 
45 int main()
46 {
47     int t;
48     scanf("%d", &t);
49     while(t--)
50     {
51         scanf("%d", &n);
52             for(i=1; i<=n; i++)
53                 for(j=1; j<=n; j++)
54                     map[i][j] = (i==j?0:INF);
55         for(i=1; i<=n; i++)
56         scanf("%lf %lf", &x[i], &y[i]);
57         for(i=1; i<=n; i++)
58             for(j=1; j<=n; j++){
59                 double temp = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
60                     if(temp>=10 && temp <= 1000 && map[i][j] > temp)
61                         map[i][j] = map[j][i]=temp;                                    
62             }
63             prim();
64     }
65     return 0;
66 } 

 

 
posted on 2015-07-29 21:33  cleverbiger  阅读(280)  评论(0编辑  收藏  举报