poj 2031Building a Space Station(几何判断+Kruskal最小生成树)

0
0
1
1. 云栖社区>
2. 博客>
3. 正文

poj 2031Building a Space Station(几何判断+Kruskal最小生成树)

hjzgg 2016-04-28 11:52:17 浏览1619

``````/*
最小生成树 + 几何判断
Kruskal      球心之间的距离 - 两个球的半径 < 0 则说明是覆盖的！此时的距离按照0计算
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int f[105];
struct ball{
double x, y, z, r;
};

struct connect{
double dist;
int a, b;
};

connect c[5005];

ball b[105];

bool cmp(connect a, connect b){
return a.dist < b.dist;
}
int n;

int getFather(int x){
return x==f[x] ? x : f[x]=getFather(f[x]);
}

int Union(int a, int b){
int fa=getFather(a), fb=getFather(b);
if(fa!=fb){
f[fa]=fb;
return 1;
}
return 0;
}

int main(){
int i, j;
while(scanf("%d", &n) && n){
for(i=1; i<=n; ++i)
scanf("%lf%lf%lf%lf", &b[i].x, &b[i].y, &b[i].z, &b[i].r);
int cnt=0;
for(i=1; i<n; ++i)
for(j=i+1; j<=n; ++j){
double d = sqrt((b[i].x-b[j].x)*(b[i].x-b[j].x) + (b[i].y-b[j].y)*(b[i].y-b[j].y) + (b[i].z-b[j].z)*(b[i].z-b[j].z))
- (b[i].r + b[j].r);
c[cnt].dist= d<0 ? 0: d;
c[cnt].a=i;
c[cnt++].b=j;
}
sort(c, c+cnt, cmp);
double minSum=0.0;
for(i=1; i<=n; ++i)
f[i]=i;
for(i=0; i<cnt; ++i){
if(Union(c[i].a, c[i].b))
minSum+=c[i].dist;
}
printf("%.3lf\n", minSum);
}
return 0;
}``````

hjzgg
+ 关注

corcosa 12828人浏览