poj2031 连接所有的球,让连接的线段和最小。

来源:互联网 发布:3d教学软件 编辑:程序博客网 时间:2024/05/29 16:09
//poj2031 连接所有的球,让连接的线段和最小。 //记录所有两个球之间的线段。 最小生成树 #include <iostream>#include <string>#include <cmath>#include <iomanip>using namespace std;double inf = 10000;double x[105], y[105], z[105], r[105];double weight[105][105]; double dist[105];bool mark[105];double sum;double compute(int m, int n){double xx = (x[m] - x[n]) * (x[m] - x[n]);double yy = (y[m] - y[n]) * (y[m] - y[n]);double zz = (z[m] - z[n]) * (z[m] - z[n]);double dis = 0;dis += sqrt(xx + yy + zz);dis -= (r[m] + r[n]);return dis;}double prime(int n){dist[0] = 0;mark[0] = true;//初始化距离表 for(int i = 1; i < n; i++){dist[i] = weight[0][i];}  for(int i = 1; i < n; i++){//寻找距离党组织最近的点 double min1 = inf;int minIndex = -1;for(int j = 1; j < n; j++){if(!mark[j] && dist[j] < min1){min1 = dist[j];minIndex = j;}}//加入党组织,更新距离表 sum += dist[minIndex];dist[minIndex] = 0;mark[minIndex] = true;for(int j = 1; j < n; j++){if(!mark[j])dist[j] = (weight[minIndex][j] < dist[j])?weight[minIndex][j]:dist[j];}}return sum;}int main(){int n;cin>>n;while(n){sum = 0;for(int i = 0; i < n; i++){dist[i] = inf;for(int j = 0; j < n; j++){weight[i][j] = inf;weight[j][i] = inf;}}memset(mark, 0, sizeof(mark)); for(int i = 0; i < n; i++)   weight[i][i] = 0;  for(int i = 0; i < n; i++){cin>>x[i]>>y[i]>>z[i]>>r[i];if(i != 0){for(int j = 0; j < i; j++){double temp = compute(j, i);if(temp < 0)weight[j][i] = 0;else weight[j][i] = temp; weight[i][j] = weight[j][i];}}}cout<<fixed<<setprecision(3)<<prime(n)<<endl;cin>>n;}return 0;}

0 0
原创粉丝点击