题意:给出球形空间站数目N,以及各个空间站的三维坐标x,y,z 以及 半径r ,求将所有空间站连接的最小cost (cost就等于空间站之间的距离) 如果接触,包含,或者相交则不需要搭建桥
思路:还是一道最小生成树的题目,我们先记录每个空间站的信息,然后将所有空间站两两相连接,如果 如果接触,包含,或者相交 我们就把cost 置为1 ,否则就用距离半径之和。
把每个空间站用一个标号表示,然后记录到 向前星中 。 用prim算法 去找最小生成树即可 。
还有一点要注意的是,最后结过的输出:G++下要使用%f而不能使用%lf
完整代码;
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <vector> #include <cmath> #include <algorithm> using namespace std; const int maxn = 1000; const int maxm = 1e5; int n,m; double ans; typedef pair<double,int> pii; struct Egde{ int u,v,next; double w; }edge[maxm]; struct node{ double x,y,z,r; }space[maxn]; struct cmp{ bool operator () (pii a, pii b){ return a.first > b.first; } }; int head[maxn]; int vis[maxn]; double dist[maxn]; int top; void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dist,-1,sizeof(dist)); top = 0; ans = 0; } void add(int u,int v,double w){ int i;//更新最小边权值 for(i=head[u]; ~i; i=edge[i].next){ if(edge[i].v == v){ if(edge[i].w > w) edge[i].w = w; return ; } } edge[top].u = u; edge[top].v = v; edge[top].w = w; edge[top].next = head[u]; head[u] = top++; } void prim(int s){ int i; priority_queue<pii,vector<pii>, cmp>q; vis[s] = 1; dist[s] = 0; for(i = head[s];~i;i = edge[i].next){ int v = edge[i].v; dist[v] = edge[i].w; q.push(make_pair(dist[v],v)); } while(!q.empty()){ pii t = q.top(); q.pop(); if(vis[t.second]) continue; ans += t.first; vis[t.second] = 1; for(i = head[t.second]; ~i;i = edge[i].next){ int v = edge[i].v; if(!vis[v]&&(dist[v]>edge[i].w)||dist[v] == -1){ dist[v] = edge[i].w; q.push(make_pair(dist[v],v)); } } } } double getDist(int i,int j){ double sX = (space[i].x-space[j].x)*(space[i].x-space[j].x); double sY = (space[i].y-space[j].y)*(space[i].y-space[j].y); double sZ = (space[i].z-space[j].z)*(space[i].z-space[j].z); double dis = sqrt(sX+sY+sZ); if(dis<=(space[i].r+space[j].r)) return 0.00; else return dis-(space[i].r+space[j].r); } int main(){ while(cin>>n&&n){ // cin>>m; init(); for(int i=0; i<n;i++){ cin>>space[i].x>>space[i].y>>space[i].z>>space[i].r; } for(int i=0; i<n;i++){ for(int j=0;j<n;j++){ if(i==j) continue; add(i,j,getDist(i,j)); add(j,i,getDist(j,i)); } } prim(0);
printf("%.3f ",ans);//注意:在G++下精度要用%f来输出 如果用 %lf输出则会wa } }