【图论】洛谷P1265 公路修建(最小生成树kruskal模板题)

题目

LP1265

思路

稍微有一点需要想的。本题实际求的就是最小生成树,但是可以去掉(s-1)个最小生成树里面的最长边。

代码

#include 
#include 
#include 
#include 
#define _for(i,a,b) for(int i = a; i
#define _rep(i,a,b) for(int i = a; i<=b; i++)

using namespace std;

const int maxn = 500 + 10;
const int maxm = 250000;
int s, n, xp[maxn], yp[maxn], from[maxm], to[maxm], fa[maxn], r[maxm], cnt;
double val[maxm];

bool cmp(int a, int b) {
	return val[a] < val[b];
}

int fd(int u) {
	return fa[u] == u ? u : fa[u] = fd(fa[u]);
}

int main() {
	scanf("%d%d", &s, &n);
	_for(i, 0, n) {
		scanf("%d%d", &xp[i], &yp[i]);
	}
	_for(i, 0, n) _for(j, 0, n) if (i != j) {
		from[cnt] = i; to[cnt] = j;
		val[cnt] = sqrt(pow(abs(xp[j] - xp[i]), 2) + pow(abs(yp[j] - yp[i]), 2));
		cnt++;
	}

	_for(i, 0, n) fa[i] = i;
	_for(i, 0, cnt) r[i] = i;
	sort(r, r + cnt, cmp);
	int cnt2 = 1;
	double ans;
	_for(i, 0, cnt) {
		int e = r[i], a = fd(from[e]), b = fd(to[e]);
		if (a != b) {
			if (cnt2++ == n - s) ans = val[e];
			fa[a] = b;
		}
	}

	printf("%.2lf\n", ans);
	return 0;
}

你可能感兴趣的:(9.noip及时复习,图论,最小生成树,kruskal)