D129 最小生成树 Kruskal 算法 P2504 [HAOI2006] 聪明的猴子
D129 最小生成树 Kruskal 算法 P2504 [HAOI2006] 聪明的猴子_哔哩哔哩_bilibili
给定 M 个猴子的最大跳跃距离,N 棵树的坐标,统计有多少个猴子可以跳到所有树上。
思路
把任意两颗树之间的距离算出来,做边权
跑 Kruskal 算法找最小生成树,加边的同时记录下最大的边权 $mxd$
枚举每个猴的跳跃距离,如果跳跃距离 $\ge mxd$,就 $ans++$
相关板子:
D08【模板】最小生成树 Kruskal 算法 - 董晓 - 博客园
// 最小生成树 Kruskal算法 O(NlogN) #include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,m,k,tot,ans; int d[N],x[N],y[N],fa[N]; double mxd; pair<double,pair<int,int> >e[N]; //边集 int find(int u){ //并查集的找根 return fa[u]==u?u:fa[u]=find(fa[u]); } void kruskal(){ sort(e+1,e+k+1); //排序 for(int i=1; i<=n; i++) fa[i]=i; for(int i=1; i<=k; i++){ int x=find(e[i].second.first),y=find(e[i].second.second); if(x!=y){ fa[x]=y; mxd=e[i].first; //最大边权 if(++tot==n-1) break; } } for(int i=1; i<=m; i++)if(d[i]>=mxd)ans++; cout<<ans; } int main(){ cin>>m; //m个猴 for(int i=1; i<=m; i++) cin>>d[i]; cin>>n; //n颗树 for(int i=1; i<=n; i++) cin>>x[i]>>y[i]; for(int i=1; i<=n; i++)for(int j=1; j<=n; j++)if(i!=j){ e[++k]={sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])),{i,j}}; } kruskal(); }
浙公网安备 33010602011771号