HOJ 1614 Communication Planning for Phobos(最小生成树 计算几何)

Communication Planning for Phobos

My Tags  (Edit)
  Source : ACM ICPC North Central North America Regional 2002
  Time limit : 1 sec   Memory limit : 32 M

Submitted : 348, Accepted : 171

Life has been found on Phobos, one of the satellites of Mars! Unfortunately, the life forms there arenˇt quite as advanced as those on Earth, and they donˇt have modern communications (at least by Earth standards). The Advanced Communication Management Company (ACM) has decided to build a central office and connect the Phobosiansˇ homes for communication (telephone, television, Internet, and so forth). They naturally want to minimize their capital outlay in this effort, and they need to decide how to lay fiber optic cable (essentially on the surface) so the smallest amount is used. Since ACM uses digital broadband technology, it is only necessary that there be a cable path that connects every subscriber and the central office. That is, there does not necessarily need to be a separate cable from the central office to each subscriberˇs home.

""""

We know the precise location of each Phobosianˇs home and the planned ACM central office on the surface. These are given using longitude and latitude. Longitude is measured from an arbitrary meridian on the surface of Phobos, and has values in the range 儃180 degrees to +180 degrees. Latitude is measured from the equator, and has values in the range 儃90 degrees to +90 degrees. For planning purposes we assume Phobos is perfectly spherical, exactly 16.7 miles in diameter. The figure to the left illustrates one possible location (+80 deg longitude, +30 deg latitude).

Input

There will be one or more sets of input data. Each set will contain, in order, an integer N no larger than 100, but at least 2, followed by N pairs of real numbers, each pair giving the unique longitude and latitude, in degrees, of a Phobosianˇs home or the central office. A single integer zero will follow the last data set.

Output

For each input data set print a single line containing the data set number (1, 2, ) and the number of miles of cable required to connect all the Phobosianˇs homes and the central office; show two fractional digits in the distance.

Sample Input

3
0 0    0 90    0 -90

3
0 0    0 90    90 0

3
0 0    90 0    45 0

6
-10 10   -10 -10   0 0   90 0   80 20   100 -10

0
Sample Output
Case 1: 26.23 miles
Case 2: 26.23 miles
Case 3: 13.12 miles
Case 4: 21.16 miles

给一个球体上的一些点,让你求把这些点全连起来需要的最少的花费,连接两个点的花费为他们的距离

刚开始没看懂题意。。揣摩了半天样例都不对。。看明白了才发现是一道最小生成树。。

算距离的话有一个公式,在模版中可以看到。球体上两点利用经纬度计算角度。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const double PI = acos(-1.0);
const double EARTHR = 16.7*0.5;
struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
typedef Point Vec;
//向量+向量 = 向量,点+向量 = 点
Vec operator +(Vec A,Vec B){return Vec(A.x+B.x,A.y+B.y);}
//点-点 = 向量
Vec operator -(Point A,Point B){return Vec(A.x-B.x,A.y-B.y);}
//向量*数 = 向量
Vec operator *(Vec A,double p){return Vec(A.x*p,A.y*p);}
//向量/数 = 向量
Vec operator /(Vec A,double p){return Vec(A.x/p,A.y/p);}
bool operator <(const Point& a,const Point& b){
    return a.x<b.x || (a.x == b.x && a.y<b.y);
}
const double EPS = 1e-10;
int dcmp(double x){
    if(fabs(x)<EPS) return 0;else return x<0? -1: 1;
}
bool operator == (const Point& a,const Point &b){
    return dcmp(a.x-b.x)==0 &&dcmp(a.y-b.y) == 0;
}
double earthdis(Point a,Point b){
    double x1=PI*a.x/180.0;
    double y1=PI*a.y/180.0;
    double x2=PI*b.x/180.0;
    double y2=PI*b.y/180.0;
    return acos(cos(x1-x2)*cos(y1)*cos(y2)+sin(y1)*sin(y2));
}
int n;
struct edge{
    int u,v;
    double w;
};
vector<edge> e;
int cmp(edge a,edge b){
    return a.w<b.w;
}
int fa[105];
int findset(int x){
    return fa[x] !=x? fa[x] = findset(fa[x]):x;
}
double Kruskal(){
    sort(e.begin(),e.end(),cmp);
    for(int i=1;i<=n;i++)fa[i] = i;
    double ret = 0;
    for(int i=0;i<e.size();i++){
        int u = e[i].u,v = e[i].v;
        double w = e[i].w;
        u = findset(u),v = findset(v);
        if(u == v)continue;
        fa[u] = v;
        ret+=w;
    }
    return ret;
}
int main()
{

    Point p[105];
    int cas = 1;
    while(scanf("%d",&n),n){
        e.clear();
        for(int i=1;i<=n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i!=j){
                    edge temp;
                    temp.u = i,temp.v = j,temp.w = earthdis(p[i],p[j])*EARTHR;
                    e.push_back(temp);
                }
        printf("Case %d: %.2lf miles\n",cas++,Kruskal());
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值