POJ 2031 Building a Space Station(最小生成樹+簡單幾何)
阿新 • • 發佈:2018-12-11
題意:
在一個三位平面上有幾個球體,然後輸入資料是給你N個球的球心座標,以及半徑。科學家們想要實現各個球之間的接觸,也就是有表面的接觸。當然,兩個球之間可能會有相交的地方( dis(a,b) <= 0 ),那麼這兩個球是不用你新建道路來實現想通的。
思路:
求每個球之間球面的距離然後最小生成樹就行了。水……
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<set> #include<list> #include<deque> #include<map> #include<queue> #include<iomanip> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int maxn=105; const double eps=1e-8; const double PI = acos(-1.0); ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); } struct node { double x,y,z,r; }; double dis(node a,node b) { double t=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z))-a.r-b.r; return t>0?t:0; } node a[maxn]; int vis[maxn]; double lowc[maxn]; double prim(double cost[][maxn],int n) { double ans=0; memset(vis,0,sizeof(vis)); for(int i=1;i<n;i++) { lowc[i]=cost[0][i]; } vis[0]=1; for(int i=0;i<n-1;i++) { double minc=inf; int p; for(int j=0;j<n;j++) { if(!vis[j]&&minc>lowc[j]) { p=j; minc=lowc[j]; } } if(minc==inf) return -1; ans+=minc; vis[p]=1; for(int j=0;j<n;j++) { if(!vis[j]&&lowc[j]>cost[p][j]) { lowc[j]=cost[p][j]; } } } return ans; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0); int n; while(cin>>n&&n) { for(int i=0;i<n;i++) { cin>>a[i].x>>a[i].y>>a[i].z>>a[i].r; } double g[maxn][maxn]; for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { if(i==j) g[i][j]=0; else { g[i][j]=g[j][i]=dis(a[i],a[j]); } } } cout<<fixed<<setprecision(3)<<prim(g,n)<<endl; } return 0; }