这题与HDOJ1879有点不太一样,不能把不符合条件的边看成是已经修好的,使用克鲁斯卡尔时,碰到不符合的边直接跳过即可。
View Code
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #define D(x1,y1,x2,y2) (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))) 5 #define N 101 6 #define M 5000 7 int x[N],y[N]; 8 struct node 9 { 10 int a,b; 11 double d; 12 }edge[M]; 13 int n,m,p[N]; 14 void make_set() 15 { 16 int i; 17 for(i=0;i<n;i++) p[i]=i; 18 } 19 int find_set(int i) 20 { 21 return i==p[i]?p[i]:(p[i]=find_set(p[i])); 22 } 23 void union_set(int i,int j) 24 { 25 i=find_set(i),j=find_set(j); 26 p[j]=i; 27 } 28 int cmp(const void *a,const void *b) 29 { 30 double x,y; 31 x=((struct node*)a)->d; 32 y=((struct node*)b)->d; 33 if(x>y) return 1; 34 return -1; 35 } 36 int main() 37 { 38 int t,i,j,cnt; 39 double ans; 40 scanf("%d",&t); 41 while(t--) 42 { 43 scanf("%d",&n); 44 make_set(); 45 for(i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]); 46 m=0; 47 for(i=0;i<n;i++) 48 { 49 for(j=i+1;j<n;j++) 50 { 51 edge[m].a=i,edge[m].b=j; 52 edge[m++].d=D(x[i],y[i],x[j],y[j]); 53 } 54 } 55 qsort(edge,m,sizeof(edge[0]),cmp); 56 ans=cnt=0; 57 for(i=0;cnt<n-1&&i<m;i++) 58 { 59 if(find_set(edge[i].a)==find_set(edge[i].b)) continue; 60 if(edge[i].d<10.0||edge[i].d>1000.0) continue; 61 ans+=edge[i].d; 62 union_set(edge[i].a,edge[i].b); 63 cnt++; 64 } 65 if(cnt==n-1) printf("%.1lf\n",ans*100); 66 else printf("oh!\n"); 67 } 68 return 0; 69 }