hdu 1875畅通工程再续(最小生成树)

思路简单,最小生成树,用prim或者kruskal都可以实现,我就用的是kruskal。

但杯具的是开始一直理解错误,wa的惨不忍睹,所以尽管题很水,我也发篇文,希望可以给后来人有点帮助

 

题目中的这句话很重要:

“决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米”,

所以他给的点不一定都符合条件,在连接点时,光考虑path权值在10~1000之间的就可以了,如果path权值全部都不在10~1000直接那就

输出"oh!",否则输出最小花费。

我开始理解成,所有点都要求连通,如果实例给的点之间的权值存在超出10~1000范围的就输出"oh!",就一直悲催的wa

给一组实例:

input:

1

 

10

0 0

25 12

89 89

62 13

11 24

22 39

100 101

25 44

150 151

200 186

 

 

output:

35112.7

 

下面是代码,并查集思想

#include<stdio.h> #include<math.h> #include<stdlib.h> int n,k,father[101]; struct node { int x,y; }point[101]; struct p { int from,to; double len; }path[50001]; int cmp(const void *a,const void *b) { struct p *aa=(p *)a; struct p *bb=(p *)b; return aa->len > bb->len?1:-1; } int findfather(int x) { if(father[x]!=x) father[x]=findfather(father[x]); return father[x]; } void merge(int a,int b) { int x,y; x=findfather(a); y=findfather(b); if(x!=y)father[x]=y; } void init() { int i; for(i=0;i<101;i++) father[i]=i; } double fdist(int a1,int b1,int a2,int b2) { return sqrt(0.0 + pow(a1-a2,2) + pow(b1-b2,2) ); } void getmap() { int i,j; double l; for(i=0;i<n;i++) scanf("%d%d",&point[i].x,&point[i].y); k=0; for(i=0;i<n;i++) { for(j=0;j<n;j++) { l=fdist(point[i].x,point[i].y,point[j].x,point[j].y); if( l>=10 && l<=1000 ) { path[k].from=i; path[k].to=j; path[k].len=l; k++; } } } } int main() { int t,i; double s; scanf("%d",&t); while(t--) { scanf("%d",&n); getmap(); if(k==0) {printf("oh!/n");continue;} qsort(path,k,sizeof(path[0]),cmp); init(); for(s=0.0,i=0;i<k;i++) { if(findfather( path[i].from ) != findfather( path[i].to )) { merge(path[i].from,path[i].to); s+=path[i].len; } } printf("%.1f/n",100.0*s); } return 0; } 

你可能感兴趣的:(struct,ini,input,Path,merge,output)