POJ

来源:互联网 发布:2k17mc模式奥尼尔数据 编辑:程序博客网 时间:2024/06/06 01:30

题意:给你n个球,如果两个球是接触的那么连接就不花费,如果不是接触的那么就是接触的距离,很容易看出是个最小生成树的。

最近对ACM有点迷茫,不知道为什么,感觉看到每个题都感觉很难,也不愿意去思考,有点脑子疼。。很无奈,不知怎么取舍,毕竟我的专业不是专攻这个的。。哎,有点无奈。

#include <iostream>#include <math.h>#include <algorithm>#include <cstdio>#include <cstring>#include <string>#include <iomanip>using namespace std;const int maxn = 20000 + 20;struct node{    int come, to;    double cost;}edge[maxn];double x[maxn], y[maxn], z[maxn], r[maxn];int  fa[maxn];void init(){    for(int i = 0; i < maxn; i++)        fa[i] = i;}int getf(int x){    if(x == fa[x])        return x;    return fa[x] = getf(fa[x]);}double distance_(int i, int j){    return 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]));}int same(int x, int y){    x = getf(x);    y = getf(y);    if(x == y)        return 1;    fa[x] = y;    return 0;}bool cmp(node p1, node p2){    return p1.cost < p2.cost;}double kursual(int sum){    sort(edge, edge + sum, cmp);    init();    double ans = 0;    for(int i = 0; i < sum; i++)    {        if(!same(edge[i].come, edge[i].to))            ans += edge[i].cost;    }    return ans;}int main(){    int n;    ios::sync_with_stdio(false);    while(cin >> n && n)    {        for(int i = 0; i < n; i++)            cin >> x[i] >> y[i] >> z[i] >> r[i];        int sum = 0;        for(int i = 0; i < n - 1; i++)        {            for(int j = i + 1; j < n; j++)            {                double dis = distance_(i ,j);                if(dis <= r[i] + r[j])                {                    edge[sum].come = i;                    edge[sum].to = j;                    edge[sum++].cost = 0;                }                else                {                    edge[sum].come = i;                    edge[sum].to = j;                    edge[sum++].cost = dis - r[i] - r[j];                }            }        }        double ans = kursual(sum);        cout <<setprecision(3) << fixed <<ans << endl;    }    return 0;}

0 0
原创粉丝点击