部落划分

每合并一次,部落数减一,最终合并到合法的数量。
若i时得到nk时,不能确定w[i+1]即为答案,因为可能u[i+1].fv[i+1].f,所以还需要再往下枚举判断。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1005;
int n,k,cnt,tot;
bool flag; 
int f[N];
struct node{
	int u,v;
}a[N];
struct Node{
	int u,v;
	double w;
}edge[N*N];
bool cmp(Node a,Node b){
	return a.w<b.w;
}
int find(int x){
	if(f[x]==x) return f[x];
	return f[x]=find(f[x]);
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].u,&a[i].v);
	}
	for(int i=1;i<=n;i++) f[i]=i;
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++){
		edge[++cnt].u=i; edge[cnt].v=j; edge[cnt].w=sqrt((a[i].u-a[j].u)*(a[i].u-a[j].u)+(a[i].v-a[j].v)*(a[i].v-a[j].v));
	}
	sort(edge+1,edge+cnt+1,cmp);
	for(int i=1;i<=cnt;i++){
		int r1=find(edge[i].u);
		int r2=find(edge[i].v);
		if(r1==r2) continue;
		f[r1]=r2;
		n--;
		if(n==k){
			flag=1;	
			continue;
		}
		if(flag){
			printf("%.2f",edge[i].w);//不一定下一个就是 
			break;	
		}
	}
	return 0;
}
posted @ 2021-05-23 16:04  dfydn  阅读(101)  评论(0编辑  收藏  举报