Freckles

来源:互联网 发布:网络电视机播放器 编辑:程序博客网 时间:2024/06/06 06:36

题目网址:Freckles

题目大意:给出n个点的坐标,求出将这些点相连,这种连接方式使得所有线段长度和最小,求这个长度和为多少?

其实这道题,比最小生成树的求解多了一个步骤,因为给的是一系列的点,并不像之前的题目给的是一系列的边,我只需要将边权值排序然后kruskal就行,这道题我需要利用一个结构体存储那些输入的点,然后在求解。

#include<iostream>#include<algorithm>#include<cmath>#include<iomanip>using namespace std;int parent[101];int findroot(int x){if (parent[x] != x)parent[x] = findroot(parent[x]);return parent[x];}struct edge{int a, b;double cost;bool operator <(const edge &a)const{return cost < a.cost;}}e[6000];struct point{double x, y;//点的结构体,表示点坐标的x和ydouble getdistance(const point &a){//计算点之间的距离double tmp = (x - a.x)*(x - a.x) + (y - a.y)*(y - a.y);return sqrt(tmp);}}p[101];int main(){int n;while (cin >> n){for (int i = 0; i < n; i++){cin >> p[i].x >> p[i].y;}int size = 0;//统计边的总数for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){e[size].a = i;//边的两个顶点的编号e[size].b = j;e[size].cost = p[i].getdistance(p[j]);//边权值为两点之间的长度size++;}}sort(e, e + size);//同样的先按cost的递增次序排序for (int i = 0; i < n; i++){//对每一个节点定义为孤立的集合,以自己为根节点,并查集的知识!parent[i] = i;}double ans = 0;for (int i = 0; i < size; i++){int a = findroot(e[i].a);int b = findroot(e[i].b);if (a != b){parent[a] = b;ans += e[i].cost;}}cout << fixed << setprecision(2) << ans << endl;//精度2}return 0;}


原创粉丝点击