zoj 1203 kruskal+并查集

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
typedef struct edges
{
        int u, v;
        double w;
}edges;
double X[1000], Y[1000];
edges edge[5000]; 
int n, m;
int parent[1000];
double sum;
int cmp( const void *a, const void *b )
{
    edges aa = *( const edges *)a; 
    edges bb = *( const edges *)b;
    if( aa.w > bb.w ) return 1;
    else return -1; 
}
void UFset( )
{
     for( int i = 0; i < n; i++ )
          parent[i] = -1;
}
int Find( int x )
{
    int r;
    for( r = x; parent[r] >= 0; r = parent[r] );
    while( r != x )
    {
           int tmp = parent[x];
           parent[x] = r;
           x = tmp; 
    }
    return r;
}
void Union( int R1, int R2 )
{
     int r1 = Find( R1 );
     int r2 = Find( R2 );
     int tmp = parent[r1] + parent[r2];
     if( parent[r1] > parent[r2] )     // r2 > r1
     {
         parent[r1] = r2;
         parent[r2] = tmp;
     }  
     else
     {
         parent[r2] = r1;
         parent[r1] = tmp;
     }
}
void kruskal( void )
{
     int num = 0;
     int u, v;
     UFset( );
     for( int i = 0; i < m; i++ )
     {
          u = edge[i].u; v = edge[i].v;
          if( Find( u ) != Find( v ) )
          {
              sum += edge[i].w;
              num++;
              Union( u, v );
          }
          if( num >= n-1 )  break;  
     }
}
int main()
{
    int kcase = 0;         
    double d;
    while( scanf( "%d", &n ) && n )
    {
           kcase++;
           m = 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++ )
                {
                     edge[m].u = i;
                     edge[m].v = j;
                     d = sqrt( (X[i]-X[j]) *(X[i]-X[j]) + (Y[i]-Y[j]) *(Y[i]-Y[j]) );
                     edge[m].w = d;
                     m++;
                }
           qsort( edge, m, sizeof(edge[0]), cmp );
           sum = 0.0;
           kruskal();
           if( kcase > 1 )
               printf( "\n" );
           printf( "Case #%d:\n", kcase );
           printf( "The minimal distance is: %.2lf\n", sum );
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值