0
点赞
收藏
分享

微信扫一扫

HDU 1875 畅通工程再续——最小生成树

陈情雅雅 2022-08-17 阅读 68


先遍历所有节点求出所有节点间的距离,然后用Kruskal算法求最小生成树。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn = 110;

int par[maxn], ran[maxn];

void init(int n) {
for (int i = 0; i <= n; i++) {
par[i] = i, ran[i] = 0;
}
}

int seek(int x) {
if (par[x] == x) return x;
else return par[x] = seek(par[x]);
}

void unite(int x, int y) {
x = seek(x), y = seek(y);
if (x == y) return;
if (ran[x] == ran[y]) par[x] = y;
else {
par[y] = x;
if (ran[x] == ran[y]) ran[x]++;
}
}

struct Edge {
int u, v;
double cost;
bool operator < (const Edge &another) const {
return cost < another.cost;
}
}edge[maxn*maxn];

struct Node {
int x, y;
}node[maxn];

double cal(int x1, int y1, int x2, int y2) {
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main()
{
int T, n;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &node[i].x, &node[i].y);
}
int edge_cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
double temp = cal(node[i].x, node[i].y, node[j].x, node[j].y);
if (temp < 10 || temp > 1000) continue;
edge_cnt++;
edge[edge_cnt].u = i, edge[edge_cnt].v = j, edge[edge_cnt].cost = temp * 100.0;
}
}
sort(edge + 1, edge + 1 + edge_cnt);
init(n);
int cnt = 0;
double ans = 0.0;
for (int i = 1; i <= edge_cnt; i++) {
if (cnt == n - 1) break;
if (seek(edge[i].u) != seek(edge[i].v)) {
cnt++;
ans += edge[i].cost;
unite(edge[i].u, edge[i].v);
}
}
if (cnt == n - 1) printf("%.1lf\n", ans);
else printf("oh!\n");
}
return 0;
}



举报

相关推荐

0 条评论