hdu 1865 畅通工程再续
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1875
最小生成树,用Prim算法。
源代码:
1 #include <iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<queue> 5 #include<math.h> 6 using namespace std; 7 const double INF=100000000.0; 8 int visit[110]; 9 double d[110],w[110][110]; 10 struct 11 { 12 int x,y; 13 } re[110]; 14 15 int main() 16 { 17 int n,cas,r,i,j,ok=0; 18 double min; //之前写成int了,wa了我一晚上,想哭啊~~~~ 19 scanf("%d",&cas); 20 while(cas--) 21 { 22 scanf("%d",&n); 23 //if(m==0) break; 24 double ans=0.0; 25 memset(visit,0,sizeof(visit)); 26 for(i=1; i<=n; i++) 27 { 28 d[i]=(i==1?0:INF); 29 for(j=1; j<=n; j++) 30 { 31 if(i==j)w[i][j]=0; 32 else w[i][j]=INF; 33 } 34 } 35 for(i=1; i<=n; i++) 36 { 37 38 scanf("%d %d",&re[i].x,&re[i].y); 39 } 40 if(n==1) ok=1; 41 // printf("%f %f\n",re[1].x,re[2].x); 42 for(i=1; i<=n; i++) 43 for(j=i+1; j<=n; j++) 44 { 45 // printf("aaa%lf\n",(re[i].x-re[j].x)*(re[i].x-re[j].x)); 46 double xx=re[i].x-re[j].x; 47 double yy=re[i].y-re[j].y; 48 double dis=sqrt(xx*xx+yy*yy); 49 // printf("%lf\n",dis); 50 if(dis<10.000000||dis>1000.000000) 51 w[i][j]=w[j][i]=INF; 52 else w[i][j]=w[j][i]=dis; 53 } 54 queue<int>q; 55 q.push(1); 56 int count=1; 57 visit[1]=1; 58 while(count<n) 59 { 60 // printf("count %d\n",count); 61 min=INF; 62 ok=0; 63 int temp=q.front(); 64 q.pop(); 65 for(i=1; i<=n; i++) 66 { 67 if(visit[i]==0) 68 { 69 if(d[i]>w[temp][i]) 70 d[i]=w[temp][i]; 71 if(d[i]<min) 72 { 73 ok=1; 74 min=d[i]; 75 r=i; 76 } 77 } 78 } 79 if(ok==1) //说明有一条路小于INF 80 { 81 visit[r]=1; 82 q.push(r); 83 count++; 84 ans+=d[r]; 85 } 86 else break; 87 88 } 89 if(ok==1)printf("%.1lf\n",ans*100); 90 else printf("oh!\n"); 91 } 92 return 0; 93 }