[kuangbin带你飞]专题六 最小生成树 N - 畅通工程再续
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组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<iostream> #include<string> #include<algorithm> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<vector> #include<iomanip> #include<iostream> using namespace std; #define MAXN 105 #define INF 999999.9 /* 距离小于10或者大于1000 权值直接设置为inf */ int x[MAXN],y[MAXN],n; double g[MAXN][MAXN],lowc[MAXN]; bool been[MAXN]; double dis(int i,int j) { double t1 = x[i]-x[j],t2=y[i]-y[j]; return sqrt(t1*t1+t2*t2); } double Prim() { memset(been,false,sizeof(been)); for(int i=1;i<n;i++) { lowc[i] = g[0][i]; } lowc[0] = 0; been[0] = true; double ret = 0; for(int j=1;j<n;j++) { double Minc = INF; int k = -1; for(int i=1;i<n;i++) { if(!been[i]&&lowc[i]<Minc) { Minc = lowc[i]; k = i; } } if(k==-1) return -1; been[k] = true; ret+=Minc; for(int i=1;i<n;i++) { if(!been[i]&&lowc[i]>g[k][i]) { lowc[i] = g[k][i]; } } } return ret; } int main() { int t; cin>>t; while(t--) { cin>>n; for(int i=0;i<n;i++) { cin>>x[i]>>y[i]; } for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { double tmp = dis(i,j); if(tmp>=10.0&&tmp<=1000.0) g[i][j] = g[j][i] = tmp; else g[i][j] = g[j][i] = INF; } g[i][i] = 0.0; } double ans = Prim(); if(ans<0) cout<<"oh!\n"; else printf("%.1llf\n",ans*100); } return 0; }