题意
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
输入
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。 每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
输出
每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
样例
Sample Input
2
2
10 10
20 20
3
1 1
2 2
1000 1000
Sample Output
1414.2
oh!
AC代码
/*
第一次提交:超时。将cin换成scanf
第二次:还是超时(怀疑是kruskal函数中的那个return)
第二次:还是超时(double换成float,结果报错)
最终的原因:edge数组开的太小了,因为他存储了100个点相互之间的关系!!!!!最多有100*(100-1)/2=5010
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n,t,m,k;
int p[102];
struct Edge
{
int u;
int v;
double w;
}edge[5010];
//因为最多有100个岛屿。故他们之间的相互关系最多有100*(100-1)/2=5010条,故这里定义数组的大小为5010就可以。如果少于5010,在oj上就会不对
//岛屿位置的结构体
struct Island
{
double x;
double y;
}island[102];
bool cmp(Edge a ,Edge b)
{
return a.w<b.w;
}
int find(int x)
{
return p[x]==x?x:x=find(p[x]);
}
//基于并查集的克鲁斯卡尔算法
void kruskal()
{
for(int i=0;i<n;i++)
{
p[i]=i;
}
sort(edge,edge+k,cmp);
int num=0;
double ans=0;
for(int i=0;i<k;i++)
{
//产看这两个岛屿是否已经在一个集合里
int p1=find(edge[i].u);
int p2=find(edge[i].v);
if(p1!=p2)
{
ans+=edge[i].w; //把连接两个集合的路径长度加上
p[p1]=find(p2); //合并岛屿
num++; //记录合并动作的次数
}
//如果所有的分散岛屿到最后合并成了一个,则说明连通了
//因为共有n个岛屿,所以最多只能合并n-1次,而当合并了n-1次的时候,就说明整个森林肯定都连通了。所以,m=n-1时就已经可以输出最后结果了
if(num==n-1)
{
printf("%.1lf\n",ans*100);
return; //函数返回,从main函数中执行下一个测试样例
}
}
printf("oh!\n");
}
int main()
{
//freopen("input.txt", "r", stdin);
cin>>t;
while(t--)
{
cin>>n;
//二维坐标点用结构体存储
for(int i=0;i<n;i++)
{
cin>>island[i].x>>island[i].y;
}
//计算各个岛屿相互之间的距离。如果不用k只用i,j作为edge的下标,则很难做到“相互”
//并且图是对称的,仅保存一半即可
k=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
double instance=sqrt((island[i].x-island[j].x)*(island[i].x-island[j].x)+(island[i].y-island[j].y)*(island[i].y-island[j].y));//使用pow函数精确度不对。标准为什么
//如果距离不符合规范,则不进行保存
//u代表某个岛屿的起点,v代表终点,两道与之间路径的长度未w
if(instance>=10&&instance<=1000)
{
edge[k].u=i;
edge[k].v=j;
edge[k].w=instance;
k++;
}
}
}
kruskal();
}
return 0;
}
题源:acm.hdu.edu.cn/showproblem…