Freckles 九度OJ 1144 POJ 2560 最小生成樹模板題 Kruskal算法

題目鏈接

Description
In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad’s back to form a picture of the Liberty Bell. Alas, one of the freckles turns out to be a scar, so his Ripley’s engagement falls through.
Consider Dick’s back to be a plane with freckles at various (x,y) locations. Your job is to tell Richie how to connect the dots so as to minimize the amount of ink used. Richie connects the dots by drawing straight lines between pairs, possibly lifting the pen between lines. When Richie is done there must be a sequence of connected lines from any freckle to any other freckle.
Input
The first line contains 0 < n <= 100, the number of freckles on Dick’s back. For each freckle, a line follows; each following line contains two real numbers indicating the (x,y) coordinates of the freckle.
Output
Your program prints a single real number to two decimal places: the minimum total length of ink lines that can connect all the freckles.
Sample Input
3
1.0 1.0
2.0 2.0
2.0 4.0
Sample Output
3.41

題目大意:
平面上有n個點,給出每個點的座標,現在需要添加一些線段使得這些點能夠通過一系列的線段相連,求最小的線段總長度。

解題思路:
最小生成樹模板題,將平面上的點抽象成圖上的結點,將結點之間直接相連的線段抽象成連接結點的邊,且權值爲線段的長度。只是在開始求解最小生成樹之前,需要根據輸入信息把圖建立起來。

AC代碼:

#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define maxn 101
struct node {
	double x, y;
}list[maxn];
int tree[maxn];
int findroot(int x) {
	if (tree[x] == -1)return x;
	int tmp = findroot(tree[x]);
	tree[x] = tmp;
	return tmp;
}
bool unit(int a, int b) {
	int fa = findroot(a);
	int fb = findroot(b);
	if (fa != fb) {
		tree[fa] = fb;
		return true;
	}
	return false;
}
struct E {
	int from, to;
	double cost;
	bool operator < (const E &a) const {
		return cost < a.cost;
	}
}edge[6000];
double compute(node a, node b) {
	double tmp = (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
	return sqrt(tmp);
}
void init() {
	for (int i = 1; i < maxn; i++) {
		tree[i] = -1;
	}
}
int main() {
	int n;
	while (cin >> n) {
		init();
		for (int i = 1; i <= n; i++) {
			cin >> list[i].x >> list[i].y;
		}
		int cnt = 0;
		for (int i = 1; i <= n; i++) {//將圖建立起來
			for (int j = i + 1; j <= n; j++) {
				edge[++cnt].from = i; edge[cnt].to = j;
				edge[cnt].cost= compute(list[i], list[j]);
			}
		}
		sort(edge + 1, edge + 1 + cnt);
		double ans = 0.0;
		for (int i = 1; i <= cnt; i++) {
			if (unit(edge[i].from, edge[i].to)) {
				ans += edge[i].cost;
			}
		}
		printf("%.2f\n", ans);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章