此题依旧是套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;   
}
posted on 2011-07-18 16:59  枫叶飘泪  阅读(183)  评论(0编辑  收藏  举报