题目:http://poj.org/problem?id=2031
AC代码(C++):
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>
#define INF 0x7fffffff
#define LFINF 1e10
#define eps 1e-5
#define MAXN 100105
#define PI 3.14159265358979323846
using namespace std;
int n;
double x[105],y[105],z[105],r[105];
double map[105][105];
double dis[105];
bool vis[105];
double Prim(){
double ans = 0.0;
for(int i=0;i<n;i++)dis[i]=map[0][i];
memset(vis,false,sizeof(vis));
vis[0]=1;
for(int i=1;i<n;i++){
int next;
double tmp = LFINF;
for(int j=0;j<n;j++){
if(!vis[j]&&tmp>dis[j]){
tmp=dis[j];
next=j;
}
}
ans += tmp;
vis[next]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&dis[j]>map[next][j])
dis[j]=map[next][j];
}
}
return ans;
}
int main(){
while(cin>>n){
if(n==0)break;
for(int i = 0; i < n; i++)cin>>x[i]>>y[i]>>z[i]>>r[i];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
double tmp = 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];
if(tmp>eps){
map[i][j] = tmp;
map[j][i] = tmp;
}
else map[i][j] = map[j][i] = 0.0;
}
}
printf("%.3lf\n",Prim());
}
}
总结: 最小生成树.