POJ 2031 Building a Space Station 簡單計算幾何 + 最小生成樹

如題  :簡單計算幾何 + 最小生成樹

求出連個cell的距離  小於零距離爲零    否者就是兩球心的距離減兩球半徑

因爲邊較少所以用鄰接矩陣存儲    最後用一個prim計算最小生成樹  答案就出來了

注意  :POJ在G++中編譯的  輸出浮點型都要用f   不能用lf

下面看代碼:

#include<cstdio>
#include<cmath>
#include<cstring>
#define eps 1e-8
#define N 105
#define MAX 0x3fffffff
using namespace std;

struct cell
{
    double x,y,z,r;
}c[N];

double Dis(cell a,cell b)
{
    return 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));
}

int  n;
double edge[N][N],res,dis[N];
bool flag[N];

double prim(int s)
{
    for(int i = 0; i <= N; i++)
        dis[i] = MAX;
    memset(flag,false,sizeof(flag));
    dis[s]=0;
    flag[s]=true;
    for(int i=1; i<=n; i++)
    {
        if(dis[i]>edge[s][i])
            dis[i]=edge[s][i];
    }
    for(int i=1; i<n; i++)
    {
        int pos=-1;
        double Min=0x3f3f3f3f;
        for(int j=1; j<=n; j++)
        {
            if(!flag[j]&&dis[j]<Min)
            {
                Min=dis[j];
                pos=j;
            }
        }
        if(pos==-1)  return -1;
        res += Min;
        flag[pos]=true;
        for(int j=1; j<=n; j++)
        {
            if(!flag[j]&&edge[pos][j]<dis[j])
                dis[j]=edge[pos][j];
        }
    }
    return res;
}

int main()
{
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    #endif // LOCAL
    int i,j;
    while((scanf("%d",&n),n)!=0)
    {
        for(i = 1;i <=n; i++)
            scanf("%lf%lf%lf%lf",&c[i].x,&c[i].y,&c[i].z,&c[i].r);
        for(i = 1; i<=n; i++)
            for(j = 1; j<=n; j++)
        {
            if(i == j){edge[i][j] = MAX;continue;}
            double d = Dis(c[i],c[j])-c[i].r-c[j].r;
            if(d < eps)  edge[i][j] = 0;
            else edge[i][j] = d;
        }
        res = 0;
        double result = prim(1);
        printf("%.3f\n",result);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章