只要算出两者距离减去半径之和,就变成平面图了

/* ***********************************************
Author        :PeterBishop
Created Time  :Sat 02 Mar 2019 17:18:28 CST
File Name     :t.cpp
Origin        :P O J  2031
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;
const int MAXN=101;
double cost[MAXN][MAXN];
const double INF=10000;
bool vis[MAXN];
double lowc[MAXN];
struct node{
	double x;
	double y;
	double z;
	double r;
}p[MAXN];
double dis(node a,node b){
	double d=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z);
	d=sqrt(d)-a.r-b.r;
	if(d<0)
		d=0;
	return  d;
}
double prim(int n){
	memset(vis,false,sizeof(vis));
	double ans=0;
	for(int i=0;i<n;i++)
		lowc[i]=cost[0][i];
	vis[0]=true;
	for(int i=1;i<n;i++){
		int p;
		double minc=INF;
		for(int j=1;j<n;j++)
			if(!vis[j]&&minc>lowc[j]){
				p=j;
				minc=lowc[j];
			}
		vis[p]=true;
		ans+=minc;
		if(minc==INF)
			return -1;
		for(int j=0;j<n;j++)
			if(!vis[j]&&lowc[j]>cost[p][j])
				lowc[j]=cost[p][j];
	}
	return ans;
}
int main()
{
	//freopen("out.txt","w",stdout);
	freopen("in.txt","r",stdin);
    int n;
	while(cin>>n){
		if(n==0)
			break;
		for(int i=0;i<MAXN;i++)
			for(int j=0;j<MAXN;j++)
				cost[i][j]=i==j?0:INF;
		for(int i=0;i<n;i++){
			cin>>p[i].x>>p[i].y>>p[i].z>>p[i].r;
		}
		
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				double d=dis(p[i],p[j]);
				cost[i][j]=cost[j][i]=d;
			}
		}
		printf("%.3f\n",prim(n));
	}    
    return 0;
}