杭电 1875 畅通工程再续

此题依旧是套kruskal()的模板,只是条件有所隐含,此处要自己找出结构体val中的三个参量,并且注意到当距离d可以对应于v;

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

#include<math.h>

struct zb

{

    int x,y;

}z[110];

struct val

{

    int a,b;

    double v;

}e[10000];

int set[110];

int c;

int m;

double sum;

int cmp(const void *a,const void *b)

{

     return ((val *)a)->v > ((val *)b)->v ? 1 : -1;//注意此处的区别,因为v为double型。 

}

int find(int x)

{

    return set[x]==x ? x : find(set[x]);

}

void kruskal()

{

     sum=0;

     for(int i=1;i<m;i++)

     {

          int a=e[i].a,b=e[i].b;

          double v=e[i].v;

          int x=find(a),y=find(b);

          if(x!=y)

          {

              set[x]=y;

              sum+=v;

          }

     }

}

int main()

{

    int t;

    int x,y;

    int x1,x2,y1,y2;

    int f;

    scanf("%d",&t);

    while(t--)

    {

         m=1;

         scanf("%d",&c);

         for(int i=1;i<=c;i++)

         {

             set[i]=i;

         }

         for(int i=1;i<=c;i++)

         {

              scanf("%d%d",&x,&y);

              z[i].x=x;

              z[i].y=y;

         }

         for(int i=1;i<=c;i++)

         {

             for(int j=1;j<=c;j++)

             {

                 x1=z[i].x;

                 y1=z[i].y;

                 x2=z[j].x;

                 y2=z[j].y;

                 double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

                 if(d>=10&&d<=1000)

                 {

                     e[m].v=d;

                     e[m].a=i;

                     e[m].b=j;

                     m++;

                 }

             }

         }

         qsort(e+1,m-1,sizeof(e[0]),cmp);

         kruskal();

         f=0;

         for(int i=1;i<=c;i++)

         {

             if(set[i]==i)

                f++;

         }

         if(f!=1)

         {

              printf("oh!\n");

         }

         else

         {

              printf("%.1lf\n",sum*100);

         }

    } 

    //system("pause");

    return 0;   

}

你可能感兴趣的:(杭电)