相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
Input输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
Output每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.Sample Input
2 2 10 10 20 20 3 1 1 2 2 1000 1000
Sample Output
1414.2 oh!
代码:
#include<algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define P(a,b,c) make_pair(a,make_pair(b,c))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef pair<int,pair<int,int> >pii;
typedef long long ll;
const ll mod = 1000000007;
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
const int MAXN=110;//最大点数
const int MAXM=10005;//最大边数
int F[MAXN];//并查集使用
struct Edge { int u,v;double w; }edge[MAXM];//存储边的信息,包括起点/终点/权值
int tol;//边数,加边前赋值为0
void addedge(int u,int v,double w) {
edge[tol].u=u;
edge[tol].v=v;
edge[tol++].w=w;
}
bool cmp(Edge a,Edge b) {//排序函数,讲边按照权值从小到大排序
return a.w<b.w;
}
int find(int x) {
if(F[x]==-1)return x;
else return F[x]=find(F[x]);
}
double Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1
{
memset(F,-1,sizeof(F));
sort(edge,edge+tol,cmp);
int cnt=0;//计算加入的边数
double ans=0.0;
for(int i=0;i<tol;i++) {
int u=edge[i].u;
int v=edge[i].v;
double w=edge[i].w;
int t1=find(u);
int t2=find(v);
if(t1!=t2) {
ans+=w;
F[t1]=t2;
cnt++;
}
if(cnt==n-1)break;
}
if(cnt<n-1)return -1.0;//不连通
else return ans;
}
pair<double,double>p[1010];
double dist(int i,int j){
return sqrt((p[i].first-p[j].first)*(p[i].first-p[j].first)+(p[i].second-p[j].second)*(p[i].second-p[j].second));
}
int main(){
int t,n,m;
scanf("%d", &t);
while(t--){
tol=0;
scanf("%d",&n);
rep(i,1,n)scanf("%lf%lf",&p[i].first,&p[i].second);
rep(i,1,n)
rep(j,1,n){
if(j>i){
double d=dist(i,j);
if(d<10.0||d>1000.0)continue;
else addedge(i,j,d);
}
}
double h=Kruskal(n)*100;
if(h>=0.0)printf("%.1f", h);
else printf("oh!");
printf("\n");
}
return 0;
}