相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组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 代码 78ms
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#define CLR(a,b) memset((a),(b),sizeof(a))
#define inf 0x3f3f3f3f
#define mod 100009
#define LL long long
#define M 10000+10
#define ll o<<1
#define rr o<<1|1
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
using namespace std;
int c;
int pre[M];
struct Dot{int x,y;} dot[M];
struct edge {int from,to; double cost;}G[M];
double dis(Dot a,Dot b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
int find(int x){ return x==pre[x] ? x:pre[x]=find(pre[x]);}
void join(int x,int y){pre[find(x)]=find(y);}
int same(int x,int y){ return find(x)==find(y);}
int cmp(edge a,edge b){ return a.cost<b.cost;}
int k;
void init(){ for(int i=0;i<c;i++) pre[i]=i;}
void getmap()
{
k=0;
for(int i=0;i<c;i++)
scanf("%d%d",&dot[i].x,&dot[i].y);
for(int i=0;i<c;i++)
{
for(int j=i+1;j<c;j++)
{
double d=dis(dot[i],dot[j]);
if((fabs(d-10.0)<1e-8||d>10.0)&&(fabs(d-1000.0)<1e-8||d<1000.00))
{
G[k].from=i;
G[k].to=j;
G[k++].cost=d;
}
}
}
sort(G,G+k,cmp);
}
int check() // 判定连通的
{
int i,j;
int num=0;
for(i=0;i<c;i++)
{
if(i==pre[i]) {
num++;
if(num>1) return 0;
}
}
return 1;
}
void krus()
{
int i,j;
double sum=0;
for(i=0;i<k;i++)
{
if(!same(G[i].from,G[i].to))
{
sum+=G[i].cost;
join(G[i].from,G[i].to);
}
}
if(check()) printf("%.1lf\n",sum*100);
else puts("oh!");
}
int main()
{
int t;
scanf("%d",&t);while(t--)
{
scanf("%d",&c);
init();
getmap();
krus();
}
return 0;
}
二 prime 46ms
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#define CLR(a,b) memset((a),(b),sizeof(a))
#define inf 0x3f3f3f3f
#define mod 100009
#define LL long long
#define M 200
#define ll o<<1
#define rr o<<1|1
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
using namespace std;
int vis[M];
double mp[M][M];
double dis[M];
int n;
struct Dot { int x,y;} dot[M];
double diss(Dot a,Dot b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
void init()
{
int i,j;
for(i=0;i<n;i++) // 这个初始化
{
vis[i]=0;
for(j=0;j<n;j++)
{
if(i==j) mp[i][j]=0 ;
else mp[i][j]=mp[j][i]=inf;
}
}
}
void getmap()
{
int i,j;
for(i=0;i<n;i++)
scanf("%d%d",&dot[i].x,&dot[i].y);
for(i=0;i<n;i++) // 这里的建图 不和 kruskas 算法一样,手残 ,WA了好几次这里
{
for(j=0;j<n;j++)
{
if(i==j) continue;
double d=diss(dot[i],dot[j]);
if((fabs(d-10.0)<1e-8||d>10.0)&&(fabs(d-1000.0)<1e-8||d<1000.00))
{
mp[i][j]=mp[j][i]=d;
}
}
}
}
void prime()
{
int i,j;
double sum=0;
int now,next;
for(i=0;i<n;i++)
dis[i]=mp[0][i];
vis[0]=1; dis[0]=0;
for(j=1;j<n;j++)
{
double min=inf;
next=-1;
for(i=0;i<n;i++)
{
if(!vis[i]&&dis[i]<min)
{
min=dis[i];
next=i;
}
}
if(next==-1)
{
puts("oh!");
return ;
}
vis[next]=1; sum+=dis[next];
for(i=0;i<n;i++)
{
if(!vis[i]&&dis[i]>mp[next][i])
{
dis[i]=mp[next][i];
}
}
}
printf("%.1f\n",sum*100);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
init();
getmap();
prime();
}
return 0;
}