UVA 10034 - Freckles

这道题和连接校园一样都是求最小生成树,用kruskal算法做,点的坐标要用double型

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MAXD 150
double x[MAXD], y[MAXD], w[MAXD * MAXD], ans;
int r[MAXD * MAXD], p[MAXD], u[MAXD * MAXD], v[MAXD * MAXD];
int cas, N, n, nx, ny;

double dist( int i, int j)
{
return sqrt( (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
}

int find_set( int x)
{
return p[x] == x ? x : ( find_set( p[x]));
}

int cmp( const void *_p, const void *_q)
{
int *q = (int *)_q;
int *p = (int *)_p;
return w[*p] < w[*q] ? -1 : 1;
}

void init()
{
n = 0;
for( int i = 0; i < N; i ++)
scanf( "%lf%lf", &x[i], &y[i]);
for( int i = 0; i < N; i ++)
for( int j = i + 1; j < N; j ++)
{
u[n] = i;
v[n] = j;
w[n ++] = dist( i, j);
}
}

void kruskal()
{
ans = 0.0;
for( int i = 0; i < N; i ++)
p[i] = i;
for( int i = 0; i < n; i ++)
r[i] = i;
qsort( r, n, sizeof(r[0]), cmp);
for( int i = 0; i < n; i ++)
{
int e = r[i];
nx = find_set( u[e]);
ny = find_set( v[e]);
if( nx != ny)
{
p[nx] = ny;
ans += w[e];
}
}
}

int main()
{
scanf( "%d", &cas);
while( cas --)
{
scanf( "%d", &N);
init();
kruskal();
printf( "%.2f\n", ans);
if( cas > 0) printf( "\n");
}
return 0;
}

 

 

你可能感兴趣的:(uva)