相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
2 2 10 10 20 20 3 1 1 2 2 1000 1000
1414.2 oh!
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define INF 0xfffffff
int n;
double d[105][105];
int vis[105];
double min;
double dis[105];
struct zb
{
int x;
int y;
}a[105];
double dist(int i,int j)
{
return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)*1.0+(a[i].y-a[j].y)*(a[i].y-a[j].y)*1.0);
}
void init()//初始化各个变量!
{
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)//初始化d之后,一定要用d数组,而不能用算距离的,因为你用算距离的函数
{//不能够筛选在给定范围内的距离!
d[i][j]=d[j][i]=dist(i,j);
if(d[i][j]<10||d[i][j]>1000)
d[i][j]=d[j][i]=INF;
}//注意用d数组,而不能用距离函数,错了n次!
for(int i=1;i<=n;i++)//我们假设每个点到第1个点的距离为最小值!
dis[i]=d[1][i]; //代表第i个点到第1个点的距离!
memset(vis,0,sizeof(vis));//初始化,都没有进集合!
vis[1]=1;//第一个点先放到集合里面,然后将其他的点与集合里面的点求距离,将最小的距离的点放进集合!
}
int main()
{
int T,t;
double min;//注意是double型的!
scanf("%d",&T);
while(T--)
{
int k=1;
double s=0;
scanf("%d",&n);
init();
t=0;
for(int i=1;i<n;i++)//找n-1个点
{
min=INF;
for(int j=1;j<=n;j++)//找最小的距离
{
if(!vis[j]&&(dis[j]<min))//第j个点到集合的距离的最小值!
{
min=dis[j];
k=j;//保留最近的点到集合的距离的下标!
}
}
if(min==INF)//如果所有的未标记的点到集合的距离为无穷大,(也就是把距离近的点都进到集合里面之后,剩下距离较大的点了,)
{//到集合的距离为无穷大,也就是那些不满足条件的点不能进集合,最终肯定不能形成一棵树!
break;
}
t++;
vis[k]=1;//距离集合最小的点进集合,并进行标记
s+=min;//并且将最小的距离加到s上!
for(int j=1;j<=n;j++)//对集合外的点到集合的距离进行更新!
{
if(!vis[j]&&(dis[j]>d[j][k]))//如果加到集合里面的点距离集合外面的点的距离更近,就得将小的值赋值给dis[i]!
dis[j]=d[j][k];
}
}
if(t==n-1)//判断是否都进集合里面,如果都进集合里面,则输出最小值!
{
printf("%.1lf\n",s*100);
}
else
printf("oh!\n");
}
return 0;
}