来源:HDU 携程编程大赛第一场
简单Prim,不过用一种很高端洋气的经纬度表示方法来表示两点之间的距离。gis学的东东。把距离合到map里边,最后就是套用prim模板的问题。
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
double map[105][105];
const double pi=3.14159265358979323846;
const double INF=0x3f3f3f3f;
int pointnum;
int n;
double prim()
{
double low[105];
int flag[105];
memset(flag,0,sizeof(flag));
for(int i=1; i<=pointnum; i++)
{
low[i]=map[1][i];
}
double count=0;
flag[1]=1;
for(int i=1; i<pointnum; i++)
{
double min=INF+1;
int k;
for(int j=1; j<=pointnum; j++)
{
if(flag[j]==0 && min>low[j])
{
min=low[j];
k=j;
}
}
flag[k]=1;
count+=low[k];
for(int j=1; j<=pointnum; j++)
{
if(flag[j]==0&&low[j]>map[j][k])
{
low[j]=map[j][k];
}
}
}
return count;
}
void init()
{
for(int i=1;i<105;i++)
{
for(int j=1;j<105;j++)
map[i][j]=INF;
}
}
class latipoint
{
public:
double lat;
double lng;
};
double EARTH_RADIUS;
double rad(double d)
{
return d * pi / 180.0;
}
double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * asin(sqrt(pow(sin(a/2),2) + cos(radLat1) * cos(radLat2) *pow(sin(b/2),2)));
s = s * EARTH_RADIUS/2.0;
return s;
}
int main()
{
int testcase;
cin>>testcase;
while(testcase--)
{
init();
latipoint point[105];
double LineLength;
cin>>EARTH_RADIUS>>LineLength;
cin>>pointnum;
for(int i=1;i<=pointnum;i++)
{
cin>>point[i].lat>>point[i].lng;
}
n=pointnum*pointnum;
for(int i=1;i<=pointnum;i++)
{
for(int j=1;j<=pointnum;j++)
{
if(i!=j)
{
map[i][j]=GetDistance(point[i].lat,point[i].lng,point[j].lat,point[j].lng);
//cout<<"map"<<i<<"to:"<<j<<"is: "<<map[i][j]<<endl;
}
}
}
double ret=prim();
//cout<<"haha:"<<ret<<"hehe:"<<LineLength<<endl;
if(ret>LineLength)
cout<<"N"<<endl;
else
cout<<"Y"<<endl;
}
return 0;
}