洛谷P1265 公路修建

(Large extbf{Solution: } large{容易看出其实就是求最小生成树,可是n有5000,如果Kruskal存图空间会爆炸,那么只好写Prim。之前没写过,就当练练手。})

(Large extbf{Code: })

#include <bits/stdc++.h>
#define dol double 
#define LL long long
#define gc() getchar() 
using namespace std;
const int N = 5e3 + 5;
const LL inf = 9223372036854775807;
int n, x[N], y[N], vis[N];
dol ans;
LL dis[N];

inline int read() {
	char ch = gc();
	int x = 0, flg = 1;
	while (!isdigit(ch)) {
		if (ch == '-') flg = -1;
		ch = gc();
	}
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
	return x * flg;
}

inline LL cal(int a, int b) {
	return 1LL * (x[a] - x[b]) * (x[a] - x[b]) + 1LL * (y[a] - y[b]) * (y[a] - y[b]); //一开始这里忘了乘1LL,只有10pts 惨
}

inline void Prim() {
	int tot = 0, cur;
	while (++tot < n) {
		LL Min = inf;
		for (int i = 2; i <= n; ++i) if (!vis[i] && dis[i] < Min) Min = dis[i], cur = i;
		vis[cur] = 1; ans += sqrt((dol)dis[cur]);
		for (int i = 2; i <= n; ++i) if (!vis[i]) dis[i] = min(dis[i], cal(cur, i));
	}
	return;
}

int main() {
	n = read();
	for (int i = 1; i <= n; ++i) x[i] = read(), y[i] = read();
	for (int i = 2; i <= n; ++i) dis[i] = cal(1, i);
	vis[1] = 1; Prim();
	printf("%.2lf
", ans);
	return 0;
}
原文地址:https://www.cnblogs.com/Miraclys/p/12560845.html