剑鱼行动
ssl 1618
题目大意:
求一个平面直角坐标系中的最小生成树
原题:
题目描述
给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数
输入样例
5
0 0
0 1
1 1
1 0
0.5 0.5
输出样例
2.83
解题思路:
首先用勾股定理求出长度,然后用并查集来求最小生成树
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,w,xxx,yyy,dad[1005];
double ans;
struct rec
{int x,y;double l;
}a[1000005];
struct recc
{double xx,yy;
}b[1005];
bool cmp(rec aa,rec bb) {return aa.l<bb.l;}
int find(int dep){return dad[dep]==dep?dep:dad[dep]=find(dad[dep]);} //并查集
int main()
{scanf("%d",&n);for (int i=1;i<=n;++i){dad[i]=i;scanf("%lf %lf",&b[i].xx,&b[i].yy);for (int j=1;j<i;++j){a[++w].x=i;a[w].y=j;a[w].l=sqrt((b[i].xx-b[j].xx)*(b[i].xx-b[j].xx)+(b[i].yy-b[j].yy)*(b[i].yy-b[j].yy));//勾股定理}}sort(a+1,a+1+w,cmp);for (int i=1;i<=w;++i)if (find(a[i].x)!=find(a[i].y)){xxx=find(a[i].x);//寻找根节点yyy=find(a[i].y);dad[min(xxx,yyy)]=max(xxx,yyy);//合并ans+=a[i].l;}printf("%.2lf",ans);
}