思路
这个题唯一需要注意的就是不能用Kruskal,因为这是一张完全图,Kruskal需要统计边权,但是空间上显然不允许,所以只能用普通Prim(根据点更新)。
这个题实质上还是模板,只不过要稍微改一下,注意精度问题即可。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define INF 0x3f
#define MAXN 5010
typedef long long ll;
int n;
bool vis[MAXN];
ll dis[MAXN];
struct node{
ll x,y;
}inp[MAXN];
inline int read(){
int x=0, f=1; char ch=getchar();
while(ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
inline ll get_length(int u,int v){
return (inp[u].x - inp[v].x) * (inp[u].x - inp[v].x) * 1ll + (inp[u].y - inp[v].y) * (inp[u].y - inp[v].y) * 1ll;
}
void prim(){
memset(dis, INF, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[1]=0;
for(int i=1;i<n;++i){
int x=0;
for(int j=1;j<=n;++j){
if (!vis[j] && (x==0 || dis[j]<dis[x])) x=j;
}
vis[x]=1;
for(int j=1;j<=n;++j){
if (!vis[j]) dis[j]=std::min(dis[j], get_length(x,j));
}
}
return;
}
int main(){
n=read();
for(int i=1;i<=n;++i){
inp[i].x=read();
inp[i].y=read();
}
prim();
double ans=0;
for(int i=1;i<=n;++i) ans+=std::sqrt((double)dis[i]);
printf("%.2f\n", ans);
return 0;
}