D139 最小生成树 Kruskal 算法 P1991 无线通讯网

D139 最小生成树 Kruskal 算法 P1991 无线通讯网_哔哩哔哩_bilibili

 

P1991 无线通讯网 - 洛谷

n 个哨所,k 个可以安装卫星电话,其他安装无线电收发器,求无线电收发器的最小传输距离。

思路

对 $n$ 个哨所连边建完全图

跑 Kruskal 算法,当边加到第 $n-k$ 条时结束,第 $n-k$  条边权就是答案

因为后面的 $k$ 个哨所可以安装卫星电话,不受距离限制,$n-k$ 个点之间需要 $n-k-1$ 条边,与那 $k$ 个点还要连一条边

相关板子:

D08【模板】最小生成树 Kruskal 算法 - 董晓 - 博客园

 

// 最小生成树 Kruskal算法 O(MlogM)
#include<bits/stdc++.h>
// #define int long long
using namespace std;

const int N=510,M=N*N/2;
int n,k,m,tot,fa[N];
double ans;
struct A{int x,y;}a[N]; //坐标
struct E{int x,y; double w;}e[M]; //边集

int find(int u){ //并查集的找根
  return fa[u]==u?u:fa[u]=find(fa[u]);
}
void kruskal(){
  for(int i=1; i<=n; i++) fa[i]=i;
  sort(e+1,e+m+1,[&](E a,E b){return a.w<b.w;});
  for(int i=1; i<=m; i++){
    int x=find(e[i].x),y=find(e[i].y);
    if(x!=y){
      fa[x]=y;
      ans=e[i].w;
      if(++tot==n-k) break;
    }
  }
  printf("%.2lf\n", ans);
}
signed main(){
  cin>>k>>n; //k:可安装的卫星电话的哨所数,n:哨所的数量
  for(int i=1; i<=n; i++) cin>>a[i].x>>a[i].y;
  for(int i=1; i<=n; i++)for(int j=1; j<i; j++)
    e[++m]={i,j,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))};
  
  kruskal();
}

 

posted @ 2026-04-19 08:38  董晓  阅读(71)  评论(0)    收藏  举报