poj2031最小生成树(建图)(注意c++与g++的区别)

来源:互联网 发布:淘宝一个差评扣多少分 编辑:程序博客网 时间:2024/05/17 08:04
/*题意:已知n个球,已知各个点的坐标和半径,求使各个求相连所需的桥的最短长度Sample Input310.000 10.000 50.000 10.00040.000 10.000 50.000 10.00040.000 40.000 50.000 10.000230.000 30.000 30.000 20.00040.000 40.000 40.000 20.00055.729 15.143 3.996 25.8376.013 14.372 4.818 10.67180.115 63.292 84.477 15.12064.095 80.924 70.029 14.88139.472 85.116 71.369 5.5530Sample Output20.0000.00073.834*//*思路:边权 = 球距 = 球心距 - 半径1 - 半径2注意若球距为负数,则视为0。这道题我也是醉了。g++wa,c++就a了。看了网上的讨论,说是对于双精度,g++输出用%f,c++输出用%lf,就a了,否则就会wa。具体见:http://www.cnblogs.com/dongsheng/archive/2012/10/22/2734670.html*/#include <cstdio>#include <algorithm>#include <cmath>#define N 105using namespace std;const double inf = 999999999.0;typedef struct node {double x; double y; double z; double r;}point;point a[N];typedef struct note{int u; int v; double w;}edge;edge e[N*N];int n, m;int f[N];int cmp(edge a, edge b){if (a.w < b.w)return 1;else return 0;}double dis(int i, int j){return sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2) + pow(a[i].z - a[j].z, 2));}void init(){for (int i = 0; i < n; i++)f[i] = i;}int find(int x){return x == f[x] ? x : f[x] = find(f[x]);}int merge(int x, int y){int t1, t2;t1 = find(x); t2 = find(y);if (t1 != t2) { f[t2] = t1; return 1; }return 0;}int main(){while (scanf("%d", &n) != EOF && n){for (int i = 0; i < n; i++)scanf("%lf%lf%lf%lf", &a[i].x, &a[i].y, &a[i].z, &a[i].r);m = 0;for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){e[m].u = i;e[m].v = j;e[m].w = max(0.0, dis(i, j) - a[i].r - a[j].r);m++;}}sort(e, e + m, cmp);init();int cnt = 0; double sum = 0.0;for (int i = 0; i < m; i++){if (merge(e[i].u, e[i].v)){cnt++;sum += e[i].w;}if (cnt == n - 1)break;}printf("%.3f\n", sum);}return 0;}

0 0
原创粉丝点击