Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组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!
最小生成树板子题吧,判断一下所有在条件范围内的边,然后跑一遍Kruskal 如果最后边数不是n-1就输出oh!
有空再补一下Prim的做法~~
#include<iostream> #include<cstdio> //EOF,NULL #include<cstring> //memset #include<cstdlib> //rand,srand,system,itoa(int),atoi(char[]),atof(),malloc #include<cmath> //ceil,floor,exp,log(e),log10(10),hypot(sqrt(x^2+y^2)),cbrt(sqrt(x^2+y^2+z^2)) #include<algorithm> //fill,reverse,next_permutation,__gcd, #include<string> #include<vector> #include<queue> #include<stack> #include<utility> #include<iterator> #include<iomanip> //setw(set_min_width),setfill(char),setprecision(n),fixed, #include<functional> #include<map> #include<set> #include<limits.h> //INT_MAX #include<bitset> // bitset<?> n using namespace std; #define rep(i,a,n) for(int i=a;i<n;i++) #define per(i,a,n) for(int i=n-1;i>=a;i--) #define fori(x) for(int i=0;i<x;i++) #define forj(x) for(int j=0;j<x;j++) #define memset(x,y) memset(x,y,sizeof(x)) #define memcpy(x,y) memcpy(x,y,sizeof(y)) #define all(x) x.begin(),x.end() #define readc(x) scanf("%c",&x) #define read(x) scanf("%d",&x) #define read2(x,y) scanf("%d%d",&x,&y) #define read3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define print(x) printf("%d ",x) #define lowbit(x) x&-x #define lson(x) x<<1 #define rson(x) x<<1|1 #define pb push_back #define mp make_pair typedef pair<int,int> P; typedef long long LL; typedef long long ll; const double eps=1e-8; const double PI = acos(1.0); const int INF = 0x3f3f3f3f; const int inf = 0x3f3f3f3f; const int mod = 1e9+7; const int MAXN = 1e6+7; const int maxm = 1; const int maxn = 10000+10; int T; int n; double x[maxn],y[maxn]; int cnt,tot; double ans ; int pre[maxn]; struct rood{ int st,ed; double w; bool operator < (rood b) const{ return w < b.w ; } }rod[maxn]; struct node{ double x,y; }pot[maxn]; int find(int x) {return x == pre[x] ? x : pre[x] = find(pre[x]);} bool join(int x,int y){ if(find(x) != find(y)) { pre[find(y)] = find(x); return true; } return false; } double cmp(node a,node b){ double ans = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); return sqrt(ans); } void kruskal(){ for(int i = 0 ;i < cnt ; i++){ int mp1 = find(rod[i].st); int mp2 = find(rod[i].ed); if(join(mp1,mp2)) { ans += rod[i].w; tot++; } } } int main(){ read(T); while(T--){ read(n); for(int i = 0 ; i < n; i++){ scanf("%lf %lf",&pot[i].x,&pot[i].y); } memset(rod,0); ans = 0; cnt = tot = 0; for(int i = 0 ; i < maxn ;i ++) pre[i] = i; for(int i = 0 ; i < n - 1; i++){ for(int j = i + 1; j < n ; j++){ double dist = cmp(pot[i],pot[j]); if( dist >= 10 && dist <= 1000) { rod[cnt].st = i; rod[cnt].ed = j; rod[cnt++].w = dist; } } } sort(rod,rod + cnt); kruskal(); if(tot != n-1) printf("oh! "); else printf("%.1lf ",ans * 100); } }