poj2031(最小生成树)

来源:互联网 发布:看小说软件 编辑:程序博客网 时间:2024/05/16 08:54

http://poj.org/problem?id=2031

题意:给若干三为坐标的点,(x,y,z,r)形成的球面。若两个球有重叠,则不用建连通桥,否则连通桥的长度为球面间的距离。问若要使球连通,则最少桥要多长?

思路:比平常的MST多了一个建图而已,今天突然发现memset对bool函数没有用啊。。。

#include <iostream>#include <cmath>#include <cstring>using namespace std;const int INF = (1 << 30) -1;struct node{double x;double y;double z;double r;};node a[201];bool v[202];double dis[202][202];double d[202];int n;double getdis(int i, int j){double d = sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x) + (a[i].y-a[j].y)*(a[i].y-a[j].y) +(a[i].z-a[j].z)*(a[i].z-a[j].z));if (d > a[i].r+a[j].r) return d - a[i].r-a[j].r;else return 0;}double prime(int n){memset(v,sizeof(v),0);memset(d,sizeof(d),0);v[0] = 1;double min;int k;double ans = 0;for (int i = 1; i < n; i++){d[i] = dis[0][i];v[i] = 0;//cout << ":" << d[i] << endl;}for (int i = 1; i < n; i++){min = INF;for (int j = 0; j < n; j++){//cout << "*" << j << " : " << v[j] << endl;if (!v[j] && d[j] < min){k = j;min = d[j];//cout <<"::" <<min << endl;}}ans += min;v[k] = 1;for (int j = 0; j < n; j++)if (!v[j] && dis[k][j] < d[j])d[j] = dis[k][j];}return ans;}int main(){while(cin >> n && n != 0){memset(dis,sizeof(dis),0);for (int i = 0; i < n; i++)cin >> a[i].x >> a[i].y >> a[i].z >> a[i].r;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (i != j){dis[i][j] = getdis(i,j);//cout << i+1 << " " <<  j+1 << ":" << dis[i][j] << endl;}else dis[i][j] = INF;printf("%.3f\n", prime(n)); }}


0 0