POJ 2349 Arctic Network

题意为给定一堆坐标,以及n个可以使距离变为0的路径条数(放卫星),求一个生成树,使得最大的边最小。

由最小生成树的性质我们可以知道,对于每一条边,一定是第x大里最小的,否则一定会有一个边来替换,这个就不是生成树了。所以我们可以跑一遍最小生成树,然后第n大的边就是答案了。

下附AC代码。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#define maxn 250005
using namespace std;
struct po
{
	double x,y;
}pos[505];
double finddis(int i,int j)
{
	return sqrt((pos[i].x-pos[j].x)*(pos[i].x-pos[j].x)+(pos[i].y-pos[j].y)*(pos[i].y-pos[j].y));
}
int q,m,n,cnt,cnt1;
int u[maxn],e[maxn],temp[maxn],fa[maxn];
double tt[maxn];
double w[maxn];
double cmp(int i,int j)
{
	return w[i]<w[j];
}
int find(int x)
{
	return fa[x]==x? x : fa[x]=find(fa[x]);
}
double kruskal()
{
	for(int i=1;i<=m;i++)
	fa[i]=i;
	for(int i=1;i<=cnt;i++)
	temp[i]=i;
	sort(temp+1,temp+cnt+1,cmp);
	double ans=0;
	for(int i=1;i<=cnt;i++)
	{
		int t=temp[i];
		int x=find(u[t]);
		int y=find(e[t]);
		if(x==y) continue;
		ans+=w[t];
		cnt1++;
		tt[cnt1]=w[t];
		fa[x]=y;
	}
	return ans;
}
int main()
{
	scanf("%d",&q);
	while(q--)
	{
		cnt=0;
		cnt1=0;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%lf%lf",&pos[i].x,&pos[i].y);
		}
		
		for(int i=1;i<=m;i++)
		for(int j=1;j<=m;j++)
		if(i!=j)
		{
			cnt++;
			double d=finddis(i,j);
			u[cnt]=i;
			e[cnt]=j;
			w[cnt]=d;
		}
		kruskal();
		printf("%.2f\n",tt[cnt1-n+1]);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值