题目意思
给你n个小岛,现在给出你这n个小岛的坐标,如果两小岛之间的距离在10~1000之间就可以建桥,建桥的费用为100元/米。现在让你求要将所有的小岛连通的最小花费。
解题思路
这就是一道最小生成树的题,不过是求出坐标之间的距离算最小生成树,然后再乘以花费即可。但是要注意用kruskal算法时的控制结束条件,点数比较多,控制不好就会超时。。。。
代码部分
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct node
{
int x,y;
double len;///两小岛之间的距离
}cost[110*110];
int x1[110],y1[110];
int pre[110];
int n;
bool cmp(node a,node b)
{
return a.len<b.len;
}
int Find(int x)
{
if(pre[x]==x)
return x;
return pre[x]=Find(pre[x]);
}
bool join(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
pre[fx]=fy;
return 1;
}
return 0;
}
int main()
{
int t;
int k;
double x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
pre[i]=i;
for(int i=1; i<=n; i++)
{
scanf("%d%d",&x1[i],&y1[i]);
}
k=0;
for(int i=1; i<=n; i++)
{
for(int j=i+1; j<=n; j++)
{
cost[k].x=i;
cost[k].y=j;
x=(x1[i]-x1[j])*(x1[i]-x1[j]);
y=(y1[i]-y1[j])*(y1[i]-y1[j]);
double temp=sqrt(x+y);
cost[k].len=temp;
k++;
}
}
sort(cost,cost+k,cmp);
double sum=0;
for(int i=0; i<k; i++)
{
if(cost[i].len>=10&&cost[i].len<=1000&&join(cost[i].x,cost[i].y))
{
sum+=cost[i].len;
}
}
int cnt=0;
bool flag=0;
for(int i=1; i<=n; i++)
{
if(i==pre[i])
cnt++;
if(cnt>1)
{
flag=1;
break;
}
}
if(flag)
printf("oh!\n");
else
printf("%.1lf\n",sum*100);
}
return 0;
}