题目链接
思路:最小生成树问题,由于题目只给出n个点,所有你需要手动连n*(n-1)条边,每个点用pair<double,double> 存,然后自定义结构体存所有边,然后跑一遍Kruskal。
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define x first
#define y second
using namespace std;
const int N = 110,M = N*N;
struct Node
{
double x,y;
}node[N];
struct Edge
{
int a,b;
double w;
bool operator<(const Edge & W)const
{
return w<W.w;
}
}e[M];
int n,m;
int p[N];
inline int find(int x)
{
if(x!=p[x])p[x]=find(p[x]);
return p[x];
}
inline double get(Node &a,Node &b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
while(~scanf("%d",&n))
{
m=0;
for(int i=1;i<=n;i++)
{
scanf("%lf%lf", &node[i].x, &node[i].y);
}
for(int i=1;i<=n;i++)
{
for (int j = 1; j <= i; j ++ )
{
e[m++]={i,j,get(node[i],node[j])};
}
}
sort(e,e+m);
for(int i=1;i<=n;i++)p[i]=i;
double res=0;
for(int i=0;i<m;i++)
{
int a=e[i].a,b=e[i].b;
double w=e[i].w;
if(find(a)!=find(b))
{
p[find(a)]=find(b);
res+=w;
}
}
printf("%.2lf\n",res);
}
return 0;
}