【图论】【最小生成树】【Kruskal】剑鱼行动

DescriptionDescriptionDescription

给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数

InputInputInput

第一行nnn,第222n+1n+1n+1行为第iii个点的坐标

OutputOutputOutput

他们的最小生成树

SampleInputSample InputSampleInput
5
0 0
0 1
1 1
1 0
0.5 0.5 
SampleOutputSample OutputSampleOutput
 2.83

思路

先用勾股定理建边
然后用KruskalKruskalKruskal

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct whw
{
	double x,s,y;
}wh[6250250];
double Place[225][2];
double Ans;
int Fa[5025];
int n,t;
int Find(int k)
{
	while(Fa[k]!=k)k=Fa[k];
	return k;
}
//bool Fi()
//{
//	int k=Find(1);
//	for(int i=2;i<=n;++i)
//		if(k!=Find(i))return 0;
//		else k=Find(i);
//}
bool Cmp(whw i,whw j)
{return i.s<j.s;}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%lf%lf",&Place[i][0],&Place[i][1]);
		for(int j=1;j<i;++j)//建边
		{
			wh[++t].x=i;wh[t].y=j;
			double xx=abs(Place[i][0]-Place[j][0]);
			double yy=abs(Place[i][1]-Place[j][1]);
			wh[t].s=sqrt(xx*xx+yy*yy);
		}
		Fa[i]=i;
	}
	sort(wh+1,wh+t+1,Cmp);
	for(int i=1;i<=t;++i)
//		if(!Fi())//优化,防止所有点都在一个集合里却还在搜(貌似更慢了)
		{
			int x=Find(wh[i].x);
			int y=Find(wh[i].y);
			if(x!=y)
			{
				Fa[max(x,y)]=Fa[min(x,y)];
				Ans+=wh[i].s;
			}
		}
	printf("%.2lf",Ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值