Hdu 1875 畅通工程再续

刚学最小树,理解不算难,只是敲起来有点慢,这个题也不算复杂只是没有直接告诉你节点和权值而已,你自己算一下存起来然后还是最小树的基本题型,代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<time.h>
#include<map>
#include<ctype.h>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
int f[30003];
void in(int n)
{
    int i;
    for(i=0; i<=n; i++)
        f[i]=i;
}
int fd(int x)
{
    if(f[x]==x)
        return x;
        return f[x]=fd(f[x]);
}
struct DD
{
    int n1,n2;
    int x,y;
    double w;
} A[300003];
bool cmp(DD a,DD b)
{
    return a.w<b.w;
}
int main()
{
    int t,n,i,j,k;
    scanf("%d",&t);
    while(t--)
    {
        int h=0;
        int cou=0;
        double sum=0;
        scanf("%d",&n);
        in(n);

        for(i=0; i<n; i++)
            scanf("%d%d",&A[i].x,&A[i].y);//存坐标
        for(i=0; i<n-1; i++)
        {
            for(j=i+1; j<n; j++)
            {
                A[h].n1=i;//此处是存两个节点,就是相连的顶点
                A[h].n2=j;
                A[h].w=sqrt((A[i].x-A[j].x)*(A[i].x-A[j].x)+(A[i].y-A[j].y)*(A[i].y-A[j].y));//边的权值
                h++;
            }
        }
        sort(A,A+h,cmp);
        for(i=0; i<h; i++)
        {
            int xx=fd(A[i].n1);
            int yy=fd(A[i].n2);
            if(A[i].w<10)//本来这两个地方判断条件弄得很细但是过不去,给条件放宽就过了
                continue;
            if(A[i].w>1000)
                break;
            if(xx!=yy)
            {
                f[xx]=yy;
                sum+=A[i].w;
                cou++;
            }
            if(cou==n-1)
                break;

        }
        if(cou==n-1)
            printf("%.1f\n",sum*100);
        else
            printf("oh!\n");

    }
}

 

posted @ 2018-04-10 22:56  NoRain丶  阅读(88)  评论(0编辑  收藏  举报