您的位置:首页 > 其它

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

2014-08-29 19:30 387 查看


Communication Planning for Phobos

My Tags (Edit)
Source : ACM
ICPC North Central North America Regional 2002
Time limit : 1 secMemory 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: