题目大意:给定一些个球的圆心与半径,如果两个球之间相交,则他们之间连通,否则不连通,问还需要连多长的边使所有球都连通
解题思路:一个已存在边的最小生成树,只不过题目太难读了,任意两个球,如果连通则边权为0,否则边权为d-r1-r2,d是两球圆心坐标之间的距离,r1与r2分别为两个球的半径,这样求一个最小生成树,将所有球连接起来
#include<stdio.h>
#include<math.h>
#define inf 100000000
#define N 110
struct point
{
double x,y,z,r;
}a[110];
double map[N][N],d[N];
bool visted[N];
int n;
double distance(point a,point b)
{
double d= sqrt( (a.x-b.x) *(a.x-b.x)+ (a.y-b.y) *(a.y-b.y) + (a.z-b.z) *(a.z-b.z) )-a.r-b.r;
if(d>0)
return d;
else
return 0.0;
}
double prime(int root)
{
int i,j,index;
double min;
for(i=0;i<n;i++)
{
d[i]=map[root][i];
visted[i]=0;
}
visted[root]=1;
double sum=0.0;
for(i=1;i<n;i++)
{
min=inf;
for(j=0;j<n;j++)
if(!visted[ j ] && min>d[j] )
{
min=d[j];
index=j;
}
visted[index]=1;
sum+=min;
for(j=0;j<n;j++)
if(!visted[j] && map[index][j]<d[j])
{
d[j]=map[index][j];
}
}
return sum;
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=0;i<n;i++)
scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z,&a[i].r);
for(i=0;i<n;i++)
{
map[i][i]=0.0;
for(j=i+1;j<n;j++)
map[i][j]=map[j][i]=distance(a[i],a[j]);
}
// for(i=0;i<n;i++)
//{
// for(j=0;j<n;j++)
// printf("%lf ",map[i][j]);
// printf("\n");
// }
printf("%.3lf\n", prime(0));
}
return 0;
}
poj 2031 最小生成树(prim)
最新推荐文章于 2024-10-11 16:56:58 发布