洛谷 P4047 [JSOI2010]部落划分

这道题其实就是无线通讯网的双倍经验啦,只是在输出的时候不同罢了。还是一样的\(kruskal\)算法,但是在求的时候,应该在\(now=n-k+1\)的时候结束。本来到\(n-k\)就行了的,但是由于\(n-k+1\)这条边是在应该部落里面的,不能算,所以要找到第一个不在一个部落里面的边。

代码:

#include <bits/stdc++.h>
using namespace std;
struct node{
	int l , r;
	double w;
};
int n , k , tot , now;
int fa[1010];
double ans;
double dx[1010] , dy[1010];
node e[100000010];
double work(int i , int j){
	return sqrt((dx[i] - dx[j]) * (dx[i] - dx[j]) + (dy[i] - dy[j]) * (dy[i] - dy[j]));
}
bool cmp(node x , node y){
	return x.w < y.w;
}
int find(int x){
	if(x == fa[x]) return x;
	return fa[x] = find(fa[x]);
}
int main(){
	cin >> n >> k;
	for(int i = 1; i <= n; i++) cin >> dx[i] >> dy[i];
	for(int i = 1; i <= n; i++)
		for(int j = 1; j < i; j++){
			tot++;
			e[tot].l = i;
			e[tot].r = j;
			e[tot].w = work(i , j);
		}
	sort(e + 1 , e + tot + 1 , cmp);
	for(int i = 1; i <= n; i++) fa[i] = i;
	for(int i = 1; i <= tot; i++){
		if(now == n - k + 1) break;
		int x = find(e[i].l) , y = find(e[i].r);
		if(x == y) continue;
		now++;
		ans = e[i].w;
		fa[x] = y;
	}
	printf("%.2f" , ans);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/bzzs/p/13195273.html