畅通工程再续
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 }