D139 最小生成树 Kruskal 算法 P1991 无线通讯网
D139 最小生成树 Kruskal 算法 P1991 无线通讯网_哔哩哔哩_bilibili
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(); }
浙公网安备 33010602011771号