Underground Cables

Underground Cables

Description

A city wants to get rid of their unsightly power poles by moving their power cables underground. They have a list of points that all need to be connected, but they have some limitations. Their tunneling equipment can only move in straight lines between points. They only have room for one underground cable at any location except at the given points, so no two cables can cross. 

Given a list of points, what is the least amount of cable necessary to make sure that every pair of points is connected, either directly, or indirectly through other points? 

Input

There will be several test cases in the input. Each test case will begin with an integer N(2<=N<=1, 000), which is the number of points in the city. On each of the next N lines will be two integers, X and Y(- 1, 000<=X, Y<=1, 000), which are the (X, Y) locations of the N points. Within a test case, all points will be distinct. The input will end with a line with a single 0. 

Output

For each test case, output a single real number, representing the least amount of cable the city will need to connect all of its points. Print this number with exactly two decimal places, rounded. Print each number on its own line with no spaces. Do not print any blank lines between answers. 

Sample Input

4
0 0
0 10
10 0
10 10
2
0 0
10 10
0

Sample Output

30.00
14.14

题意:链接所有点的最小值
解法:最小生成树

#include <iostream>
using namespace std;
#include <math.h>
#include <stdio.h>

struct Node{
    double val;
    int x, y;
    void operator=(Node& other) {
        val = other.val;
        x = other.x;
        y = other.y;
    }
};

int n, m, f[2000], a[2000][3], tot;
Node heap[2000000];

int sqr(int x) {
    return x*x;
}

void up(int x) {
    while (x > 1 && heap[x].val < heap[x/2].val) {
        Node temp;
        temp = heap[x];
        heap[x] = heap[x/2];
        heap[x/2] = temp;
        x = x/2;
    }
}

void down(int x) {
    while (1) {
        if (x*2 > tot) break;
        int o = x*2;
        if (o+1 <= tot && heap[o+1].val < heap[o].val) o = o+1;
        if (heap[o].val < heap[x].val) {
            Node temp;
            temp = heap[x];
            heap[x] = heap[o];
            heap[o] = temp;
            x = o;
        } else break;
    }
}

int get(int x) {
    if (x == f[x]) return x;
    f[x] = get(f[x]);
    return f[x];
}

int main() {
    //freopen("h.in","r",stdin);

    cin >> n;
    while (n != 0) {
        for (int i = 1; i <= n; i++) {
            cin >> a[i][1] >> a[i][2];
            f[i] = i;
        }
        tot = 0;
        for (int i = 1; i <= n; i++)
            for (int j = i+1; j <= n; j++) {
                double dis = sqrt(sqr(a[i][1]-a[j][1])+sqr(a[i][2]-a[j][2]));
                tot++;
                heap[tot].val = dis;
                heap[tot].x = i;
                heap[tot].y = j;
                up(tot);
            }
        double ans = 0;
        for (int k = 1; k <= n-1; k++) {
            while (get(heap[1].x) == get(heap[1].y)) {
                heap[1] = heap[tot];
                tot--;
                down(1);
            }
            ans = ans+heap[1].val;
            int fx = get(heap[1].x), fy = get(heap[1].y);
            f[fx] = fy;
            heap[1] = heap[tot];
            tot--;
            down(1);
        }
        printf("%.2lf\n", ans);
        cin >> n;
    }

    //fclose(stdin);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值