poj 2031 最小生成树(prim)

本文介绍了一种解决球形对象间通过最小生成树连接的问题。算法首先计算各球形对象间的有效距离,若两球相交则视为距离为0,否则计算实际距离减去两球半径之和。利用Prim算法找到最小生成树,实现所有球形对象的最短连接路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给定一些个球的圆心与半径,如果两个球之间相交,则他们之间连通,否则不连通,问还需要连多长的边使所有球都连通

解题思路:一个已存在边的最小生成树,只不过题目太难读了,任意两个球,如果连通则边权为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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值