题目链接:
http://write.blog.csdn.net/postedit?ref=toolbar
题意:
在三维空间中有N个球形空间站,给出每个空间站的三维坐标x,y,z 和半径.其中空间站之间可能存在相交,包含,相离等情况。如果非相离则两空间站的距离为0。求连同所有空间站的最小生成树。
题解:
三维构图两空间站的距离等于两圆心距离减去两圆的半径 如果距离小于0,则距离为0
在套kruskal模板即可
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct node { int u,v; double w; } edge[10005]; double map[105][4],ans; int fa[105]; int m,s; int cmp(node a,node b) { return a.w<b.w; } int find(int x) { int d=x,t; while(fa[d]>=0) d=fa[d]; while(x!=d) //压缩路径 { t=fa[x]; fa[x]=d; x=t; } return d; } void Kruskal() { int r1,i,j,r2,n=0,ss; for(i=0; i<s; i++) { r1=find(edge[i].u),r2=find(edge[i].v); if(r1!=r2) { n++; ss=fa[r1]+fa[r2]; ans+=edge[i].w; if(fa[r1]<fa[r2]) fa[r1]=ss,fa[r2]=r1; else fa[r1]=r2,fa[r2]=ss; } if(n==m-1) break; } return; } int main() { int i,j; double weight; while(scanf("%d",&m)&&m) { ans=s=0; memset(fa,-1,sizeof(fa)); for(i=1; i<=m; i++) { scanf("%lf%lf%lf%lf",&map[i][0],&map[i][1],&map[i][2],&map[i][3]); for(j=1; j<i; j++) { edge[s].u=j,edge[s].v=i; weight=sqrt(pow(map[i][0]-map[j][0],2)+pow(map[i][1]-map[j][1],2)+pow(map[i][2]-map[j][2],2)); if(weight>map[i][3]+map[j][3]) //距离 edge[s++].w=weight-map[i][3]-map[j][3]; else edge[s++].w=0; } } sort(edge,edge+s,cmp); Kruskal(); printf("%.3lf\n",ans); } return 0; }
时间: 2024-10-05 05:13:01