此题依旧是套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; }