题目大意
FJ的N头牛(1≤N≤1000)为了在他们之间传播信息, 想要组织一个"哞哞广播"系统. 奶牛们决定去用步话机装备自己而不是在很远的距离之外互相哞哞叫, 所以每一头奶牛都必须有一个步话机. 这些步话机都有一个限制传播半径, 但是奶牛们可以间接地通过中间奶牛传播信息, 所以并不是每头牛都必须直接向其他每一头奶牛连边.
奶牛们需要去决定多少钱花在步话机上, 如果他们花了$X, 那么他们都将会得到sqrt(x)距离的步话机. 所以, 两头牛之间的欧几里得距离平方最多是X. 请帮助奶牛们找到最小的X使得图是强连通的.、
题目分析
因为“奶牛们可以间接地通过中间奶牛传播信息”,所以我们要找到就是像 最小生成树 类似的东西。
既然 N 最大为1000,所以我们可以直接考虑 N^2 建边,然后 Kruskal 找出最小生成树即可。(注意用 double 存边权)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=1e3+10; 4 5 struct Edge{ 6 int u,v; 7 double dis; 8 }e[MAXN*MAXN]; 9 inline bool cmp(Edge x,Edge y){ 10 return x.dis<y.dis; 11 } 12 double ans; 13 int n,cnt; 14 int f[MAXN]; 15 int xx[MAXN],yy[MAXN]; 16 17 inline int Find(int x){ 18 return f[x]==x?x:f[x]=Find(f[x]); 19 } 20 inline void Kruskal(){ 21 int tot=0; 22 for(int i=1,ex,ey;i<=cnt;++i){ 23 ex=Find(e[i].u); 24 ey=Find(e[i].v); 25 if(ex!=ey){ 26 f[ex]=ey; 27 ans=max(ans,e[i].dis); 28 if(++tot==n-1) 29 break; 30 } 31 } 32 } 33 int main(){ 34 scanf("%d",&n); 35 for(int i=1;i<=n;++i) 36 f[i]=i; 37 for(int i=1;i<=n;++i) 38 scanf("%d%d",&xx[i],&yy[i]); 39 for(int i=1;i<=n;++i) 40 for(int j=1;j<=n;++j) 41 if(i!=j) 42 e[++cnt]=(Edge){i,j,sqrt((xx[i]-xx[j])*(xx[i]-xx[j])+(yy[i]-yy[j])*(yy[i]-yy[j]))}; 43 sort(e+1,e+cnt+1,cmp); 44 Kruskal(); 45 printf("%.0lf",ans*ans); 46 return 0; 47 }
原文地址:https://www.cnblogs.com/LI-dox/p/11219205.html
时间: 2024-10-09 22:12:18