首页 > 其他分享 >Building a Space Station 2031 (三维的 最小生成树 prim)

Building a Space Station 2031 (三维的 最小生成树 prim)

时间:2023-04-20 18:08:19浏览次数:31  
标签:Building corridors prim Space cells 10.000 cell corridor 40.000


Building a Space Station


Time Limit: 1000MS

 

Memory Limit: 30000K

Total Submissions: 5873

 

Accepted: 2913


Description


You are a member of the space station engineering team, and are assigned a task in the construction process of the station. You are expected to write a computer program to complete the task.
The space station is made up with a number of units, called cells. All cells are sphere-shaped, but their sizes are not necessarily uniform. Each cell is fixed at its predetermined position shortly after the station is successfully put into its orbit. It is quite strange that two cells may be touching each other, or even may be overlapping. In an extreme case, a cell may be totally enclosing another one. I do not know how such arrangements are possible.

All the cells must be connected, since crew members should be able to walk from any cell to any other cell. They can walk from a cell A to another cell B, if, (1) A and B are touching each other or overlapping, (2) A and B are connected by a `corridor', or (3) there is a cell C such that walking from A to C, and also from B to C are both possible. Note that the condition (3) should be interpreted transitively.

You are expected to design a configuration, namely, which pairs of cells are to be connected with corridors. There is some freedom in the corridor configuration. For example, if there are three cells A, B and C, not touching nor overlapping each other, at least three plans are possible in order to connect all three cells. The first is to build corridors A-B and A-C, the second B-C and B-A, the third C-A and C-B. The cost of building a corridor is proportional to its length. Therefore, you should choose a plan with the shortest total length of the corridors.

You can ignore the width of a corridor. A corridor is built between points on two cells' surfaces. It can be made arbitrarily long, but of course the shortest one is chosen. Even if two corridors A-B and C-D intersect in space, they are not considered to form a connection path between (for example) A and C. In other words, you may consider that two corridors never intersect.


Input


The input consists of multiple data sets. Each data set is given in the following format.

n
x1 y1 z1 r1
x2 y2 z2 r2
...
xn yn zn rn

The first line of a data set contains an integer n, which is the number of cells. n is positive, and does not exceed 100.

The following n lines are descriptions of cells. Four values in a line are x-, y- and z-coordinates of the center, and radius (called r in the rest of the problem) of the sphere, in this order. Each value is given by a decimal fraction, with 3 digits after the decimal point. Values are separated by a space character.

Each of x, y, z and r is positive and is less than 100.0.

The end of the input is indicated by a line containing a zero.


Output


For each data set, the shortest total length of the corridors should be printed, each in a separate line. The printed values should have 3 digits after the decimal point. They may not have an error greater than 0.001.

Note that if no corridors are necessary, that is, if all the cells are connected without corridors, the shortest total length of the corridors is 0.000.


Sample Input


3
10.000 10.000 50.000 10.000
40.000 10.000 50.000 10.000
40.000 40.000 50.000 10.000
2
30.000 30.000 30.000 20.000
40.000 40.000 40.000 20.000
5
5.729 15.143 3.996 25.837
6.013 14.372 4.818 10.671
80.115 63.292 84.477 15.120
64.095 80.924 70.029 14.881
39.472 85.116 71.369 5.553
0


Sample Output


20.000 0.000 73.834


//一个简单的最小生成树问题,模板题 
//题意::
//给一个数n;表示有几个球,然后再给你n个球的球心坐标x[i],y[i],z[i],及球的半径r[i].
//让你求连接这一而求所用的最短的线是多长。
//心得::
//因为英文特别长,测试时看到这么长的题直接跳过,结果简单的题没做,很遗憾
//其实只用看一下输入输出就能明白题意了,但当时就是没看(测试完又看了一下感觉直接打脸)
//下次一定注意。 
#include<stdio.h>
#include<string.h>
#include<math.h>
#define INF 0x3f3f3f3f
double map[110][110],dis[110];
int vis[110];
int n;
void prim(int x)
{
	int i,j,k;
	double min,sum=0;
	memset(vis,0,sizeof(vis));
	for(i=1;i<=n;i++)
	{
		dis[i]=map[1][i];
	}
	dis[x]=0;
	vis[x]=1;
	for(j=1;j<n;j++)
	{
		k=1;min=INF;
		for(i=1;i<=n;i++)
		{
			if(!vis[i]&&dis[i]<min)
			{
				min=dis[i];
				k=i;
			}
		}
		if(min==INF)
			break;
		sum+=min;
		vis[k]=1;
		for(i=1;i<=n;i++)
		{
			if(!vis[i]&&dis[i]>map[k][i])
			dis[i]=map[k][i];
		}
	}
	if(sum<=0)
		printf("0.000\n");
	else
		printf("%.3lf\n",sum);
}
double x[110],y[110],z[110],r[110];
int main(){
	int i,j;
	while(scanf("%d",&n),n)
	{
		memset(map,0,sizeof(map));
		for(i=1;i<=n;i++)
			scanf("%lf%lf%lf%lf",&x[i],&y[i],&z[i],&r[i]);
		for(i=1;i<=n;i++)
		for(j=i+1;j<=n;j++)
		{
			if(map[i][j]<sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j]))-r[i]-r[j])
				map[i][j]=map[j][i]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j]))-r[i]-r[j];
			else             //这块判断如果两点间的距离是负数,给他赋值为0,负数表明这两个球之间无需连线
				        //若不判断计算时会将这些负数计算在内,显然与事实不符,当然计算的也是错误的。 
				map[i][j]=map[j][i]=0;
		}
		prim(1);				
	}
	return 0;
}


标签:Building,corridors,prim,Space,cells,10.000,cell,corridor,40.000
From: https://blog.51cto.com/u_16079508/6210089

相关文章

  • Alt+Space 快速打开切换程序 - Everything - AutoHotKey
    Alt+Space快速打开切换程序-Everything-AutoHotKey需求电脑切换任务需要用鼠标找,效率比较低,用快捷键Alt+Space打开列表,输入指定关键字回车,切换或打开程序快捷键Alt+Space打开Everything目录"E:\desktopz\everythingJump"用AutoHotKey设置下代码如下!Space::Run......
  • 修路方案 118 (prim判断最小生成树的不唯一性)
    修路方案3000ms |          内存限制:655355南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路。现在已经知道哪些城市之间可以修路,如果修路,花费是多少。现在,军师小工已经找到了一种修路的方案,能够使各个......
  • c++primer 16模板(参考B站阿西拜编程视频)
              以上还是要写一个函数,我们可以采用c++17的新语法:按条件编译,以此来作为条件:    若将特例化函数模板放在函数调用之前的话:调用compare(p1,p2)将有两个版本适合,采用特例化版本;调用compare("hi","mom")也将有两......
  • UESTC Final Pan's prime numbers 1272 (坑)
    FinalPan'sprimenumbersTimeLimit:3000/1000MS(Java/Others)   MemoryLimit:65535/65535KB(Java/Others)Submit StatusFinalPanlikesprimenumbersverymuch.Oneday,hewanttofindthesuperprimenumbers.Aprimenumbers n(n>4)......
  • C++ Primer Plus——第四章 复合类型
    C++PrimerPlus——第四章复合类型复合类型数组字符串结构共用体枚举拼接字符串常量C++允许拼接字符串字面值,即将两个用引号括起来的字符串合并成一个,事实上任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。另外第一个字符串末......
  • Again Prime? No Time. UVA - 10780
    给定m,n,求最大的k使得m^k∣n! 分解质因数   #include<iostream>#include<cstring>#include<sstream>usingnamespacestd;constintN=1e4+20;constintinf=1e9;intn,m,a[N],b[N];intprime[N],tot,vis[N];voidinit(inttop){ for(......
  • 使用js对tensorspace/three.js/webgl进行截图
    使用js对tensorspace/three.js/webgl进行截图问题分析场景:在右侧,是tensorspace库使用three.js调用webgl对模型进行渲染的画面。我需要使用js对右侧画面进行截图,并保存至本地用于分析。问题:对webgl进行截图需要进行一些特别的操作,使用html2canvas行不通。同时,针对tensorspa......
  • C Primer Plus
    CPrimerPlusC语言概述示例代码:#include<stdio.h>//预处理器指令--->提供标准的输入/输出函数,并非每个程序都会用到io/*告诉编译器把stdio.h文件的内容包含在当前程序中,stdio.h是c编译器软件包的标准部分,提供键盘输入和屏幕输出*//*这是定义了......
  • 解决flex布局中justify-content设置成space-between后因数据问题导致最后一行布局错乱
    在常用的flex布局中,当页面展示商品时,因为数据的不确定,导致justify-content设置成space-between,最后一行布局错乱1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<metahttp-equiv="X-UA-Compatible"conten......
  • C++的namespace
    这个也是和Java不同的地方,作用是为了防止类的名字冲突#include<iostream>namespacemyspace{classA{public:std::stringhead;private:std::stringbody;};}namespacemyspace2{classA{public:......