J - 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 (2N1, 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, 000XY1, 000), which are the (XY) 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.1
 
   
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>

#define N 1000001


using namespace std;

struct node
{
    int x,y;
}a[1001];
struct data
{
    int st,en,next;
    double val;
}edge[N];
int head[1001];
int tot;

int fa[1002];

int find_set(int x)
{
    if(fa[x]!=x) fa[x]=find_set(fa[x]);
    return fa[x];
}

void add(int st,int en,double val)
{
    edge[tot].st=st;
    edge[tot].en=en;
    edge[tot].val=val;
    edge[tot].next=head[st];
    head[st]=tot++;
}
double dis(int i,int j)
{
    double x=a[i].x-a[j].x;
    double y=a[i].y-a[j].y;
    return sqrt(x*x+y*y);
}
bool cmp(data a,data b)
{
    return a.val<b.val;
}

int main()
{
    int n;
    while(scanf("%d",&n),n!=0)
    {
        for(int i=0;i<n;i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        memset(head,-1,sizeof(head));
        tot=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(i!=j) add(i,j,dis(i,j));

        sort(edge,edge+tot,cmp);
        for(int i=0;i<n;i++)
            fa[i]=i;
        double ans=0.0;
        for(int i=0;i<tot;i++)
        {
            int f1=find_set(edge[i].st);
            int f2=find_set(edge[i].en);
            if(f1!=f2)
            {
                ans+=edge[i].val;
                fa[f1]=f2;
            }
        }
        printf("%.2lf\n",ans);
    }
    return 0;
}


你可能感兴趣的:(J - Underground Cables)