HDU-4463 Outlets 最小生成树
题意:就是最小生成树,题中给定了一条必须要连接的边,排序的时候不把他考虑进去即可。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <iostream> #include <cmath> using namespace std; int N; struct Point { int x, y; }; struct Edge { int a, b; double dis; bool operator < (const Edge &other) const { return dis < other.dis; } }; Point p[55]; Edge e[10000]; int idx; int set[55]; double dist(const Point &a, const Point &b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } int find(int x) { return set[x] = x == set[x] ? x : find(set[x]); } void merge(int a, int b) { set[a] = b; } int main() { int A, B; while (scanf("%d", &N), N) { idx = 1; scanf("%d %d", &A, &B); for (int i = 1; i <= N; ++i) { set[i] = i; scanf("%d %d", &p[i].x, &p[i].y); } for (int i = 1; i <= N; ++i) { for (int j = i+1; j <= N; ++j) { e[idx].a = i, e[idx].b = j; e[idx++].dis = dist(p[i], p[j]); } } double ret = 0; e[0].a = A, e[0].b = B, e[0].dis = dist(p[A], p[B]); sort(e+1, e+idx); for (int i = 0; i < idx; ++i) { int a = find(e[i].a), b = find(e[i].b); if (a != b) { ret += e[i].dis; merge(a, b); } } printf("%.2f\n", ret); } return 0; }