HDU 1875 畅通工程

..................................................................................................................................................................................................................................................................................................

首先注意数组开的大小,必须大于100*100。

将题目中给的坐标转换成点,再利用并查集,比较简单,
..................................................................................................................................................................................................................................................................................................





代码:


#include<stdio.h>
#include <iostream>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<list>
#include<vector>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 11000
int father[MAX];


struct edge   //结构体定义点与点和距离
{
    int x;
    int y;
   double w;
};
edge e[MAX];


bool cmp(edge o1,edge o2)  //排序  升序
{
    if(o1.w<o2.w)
    {
        return true;
    }
    else
    return false;
}


int Find_Set(int x)   //查找x元素所在的集合,回溯时压缩路径
{
    if(x!=father[x])
    {
        father[x]=Find_Set(father[x]);  //这个回溯时的压缩路径的精华
    }
    return father[x];
}


int Union(int x,int y)//合并x,y所在的集合
{
    x=Find_Set(x);
    y=Find_Set(y);
    if(x==y)return 0;
    else
    {
        father[x]=y;
    }
    return 1;
}


int main()
 {
    int n,m,x,t,y,i,j,count,k;
    int a[MAX],b[MAX];
    double sum;
    double h;
    scanf("%d",&t);
    while(t--)
    {
        sum=0.0;
        count=0;
        k=1;
        father[0]=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
             scanf("%d%d",&a[i],&b[i]);


        }
        for(i=1;i<=n-1;i++)
           for(j=i+1;j<=n;j++)
        {
         h=(a[j]-a[i])*(a[j]-a[i])+(b[j]-b[i])*(b[j]-b[i]);//   利用两点之间的距离公式
         if(h>=100&&h<=1000000)
         {
             father[k]=k;
             e[k].x=i;
             e[k].y=j;
             e[k].w=sqrt(h);
             k++;


         }
        }
         sort(e,e+k,cmp);
        for(i=1;i<=k;i++)
        {
             if(Union(e[i].x,e[i].y))
             {
                 count++;
                 sum+=e[i].w;
             }
        }


        if(count==n-1)
        printf("%.1lf\n",sum*100.0);
        else
        printf("oh!\n");
    }
    return 0;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值