[BZOJ1821]JSOI2010部落划分|贪心|Kruskal

              一开始总想着二分答案,发现不会贪。。

      其实就是选出最小生成树的前n-k条边之后下一条有用的边的长度,排序之后上kruskal就行了。。

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 1005
using namespace std;
struct edge{
	int s,e;
	double q; 
	edge(){}
	edge(int s,int e,double q):s(s),e(e),q(q){}
}ed[N*N];
int n,k,i,j,ne=0,s,e,fs,fe,now,fa[N],x[N],y[N];
double q;
double sqr(int a){return (double)a*a;}
double dis(int i,int j){return sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));}
bool cmp(edge a,edge b){return a.q<b.q;}
int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}
int main()
{
	scanf("%d%d",&n,&k);
	for (i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),fa[i]=i;
	for (i=1;i<=n;i++)
		for (j=i+1;j<=n;j++)
			ed[++ne]=edge(i,j,dis(i,j));
	sort(ed+1,ed+1+ne,cmp);
	now=n;
	for (i=1;i<=ne;i++)
	{
		s=ed[i].s;e=ed[i].e;q=ed[i].q;
		fs=getfa(s);fe=getfa(e);
		if (now==k&&fs!=fe) {printf("%.2lf",ed[i].q);return 0;}
		if (fs!=fe) fa[fs]=fe,now--;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值