【每日水题】最小生成树模板题

https://www.luogu.com.cn/problem/P1991

 AC代码:

/*
我将玫瑰藏于身后,晚风也变得温柔,
借着皎洁的月光,许下这一世与你白头。
那是独属于我们的花田
浪漫在原野上肆意狂奔
你摘下我头上的落叶
然后一起藏进树上看星火夜幕
多年后再闻见玫瑰森香
我想我还会想起那处山谷 和那个你

候鸟南飞,万河归海,不远千里.
你的过去我没有参与,你的未来我陪你!
地球之所以是圆的,就是为了让迷路的人重逢.
爱是天时地利的迷信,原来你也在这里!
我会用尽全力去爱你,接受你的坏脾气.
容忍的小任性,分享你的一切.
无论是开心,还是难过....

给自己喜欢的人留一句话吧:
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6;
struct yqyqyq{//yq!yq!yq!yq!永远滴神!
	double x,y;
}A[N];//存点坐标
struct wlwlwl{//wulong哥哥太帅辣!
	int u,v;
	double c;
}B[N];//存连接的两节点和边长
int C[N];//存每个节点的父节点
bool cmp1(const wlwlwl&x,const wlwlwl&y)//结构体从小到大排序
{
	return x.c<y.c;
}
int find(int x)//寻找祖宗
{
	if(C[x]!=x) C[x]=find(C[x]);
	return C[x];
}
int main()
{
	int S,P;
	scanf("%d%d",&S,&P);
	for(int i=1;i<=P;i++) scanf("%lf%lf",&A[i].x,&A[i].y);
    //用double防止精度缺失?(我也不确定)
	for(int i=1;i<=P;i++) C[i]=i;//初始化父节点
	int d=0;
	for(int i=1;i<=P;i++)
	{
		for(int j=1+i;j<=P;j++)//j>i避免重复存边
		{
			d++;
			B[d].u=i;
			B[d].v=j;
			B[d].c=sqrt((A[i].x-A[j].x)*(A[i].x-A[j].x)+(A[i].y-A[j].y)*(A[i].y-A[j].y));
    	    //两点距离公式	
        }
	}
	sort(B+1,B+d+1,cmp1);//结构体排序
	int sum=0;
	for(int i=1;i<=d;i++){
		int a=find(B[i].u);
		int b=find(B[i].v);
		if(a!=b){//连接两节点
			C[a]=b;
			sum++;
		}
		if(sum==P-S){
            //最小生成树P-1条边
            //有S个卫星电话,S-1条边
            //所以要P-1-(S-1)条边
            //即P-S条边
			printf("%.2lf\n",B[i].c);//保留两位小数
			return 0;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值