Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 5699 | Accepted: 2855 |
Description
Input
Output
Sample Input
3 10.000 10.000 50.000 10.000 40.000 10.000 50.000 10.000 40.000 40.000 50.000 10.000 2 30.000 30.000 30.000 20.000 40.000 40.000 40.000 20.000 5 5.729 15.143 3.996 25.837 6.013 14.372 4.818 10.671 80.115 63.292 84.477 15.120 64.095 80.924 70.029 14.881 39.472 85.116 71.369 5.553 0
Sample Output
20.000 0.000 73.834
Source
题目意思:给出一些球体的球心坐标和半径,需要用最短的路径连通这些球体,(这里忽略路径的宽度),先让你求出连通这些球体的最短路径。
注意:连通时不是连通球心,而是 球面。
#include<stdio.h> #include<string.h> #include<math.h> #define INF 0x3ffffff int n; double x[110],y[110],z[110],r[110]; double map[110][110]; double low[110]; int vis[110]; double fun(double x1,double y1,double z1,double r1,double x2,double y2,double z2,double r2) { if(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))-r1-r2<=0) return 0; else return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))-r1-r2; } void init() { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i==j) map[i][j]=0; else map[i][j]=INF; } } } void getmap() { int i,j; for(i=1;i<=n;i++) scanf("%lf%lf%lf%lf",&x[i],&y[i],&z[i],&r[i]); for(i=1;i<n;i++) { for(j=i+1;j<=n;j++) map[i][j]=map[j][i]=fun(x[i],y[i],z[i],r[i],x[j],y[j],z[j],r[j]); } } void prime() { int i,j,next; double min,mindis=0; int ok=0; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) low[i]=map[1][i]; vis[1]=1; for(i=1;i<n;i++) { min=INF; for(j=1;j<=n;j++) { if(!vis[j]&&min>low[j]) { min=low[j]; next=j; } } mindis+=min; vis[next]=1; for(j=1;j<=n;j++) { if(!vis[j]&&low[j]>map[next][j]) low[j]=map[next][j]; } } printf("%.3f\n",mindis); } int main() { while(scanf("%d",&n),n) { init(); getmap(); prime(); } return 0; }
poj 2031 Building a Space Station【最小生成树prime】【模板题】
原文:http://www.cnblogs.com/tonghao/p/4720268.html