P1991 无线通讯网 (最小生成树)

题目链接


Solution

\(Kruskal\) .
一直维护生成树,同时记录一下联通块数量.
如果联通块数量为 \(s+1\),那么直接结束.
最后输出答案即可.

Code

#include<bits/stdc++.h>
#define db double
using namespace std;
const int maxn=20008;

struct sj{int fr,to;db w;}a[maxn];
bool cmp(sj x,sj y){return x.w<y.w;}

db x[maxn],y[maxn],ans;
int fa[maxn],n,p,num,cnt;

int find(int x)
{if(x==fa[x])return x;else return fa[x]=find(fa[x]);}
void join(int x,int y)
{x=find(x); y=find(y);if(x!=y)fa[x]=y;}

int main()
{
    cin>>p>>n; num=n;
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&x[i],&y[i]),fa[i]=i;
    for(int i=1;i<=n;i++)
      for(int j=2;j<=n;j++)
      {
          a[++cnt].fr=i;
          a[cnt].to=j;
          a[cnt].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[j]-y[i])*(y[j]-y[i]));
      }
    sort(a+1,a+cnt+1,cmp);
    for(int i=1;i<=cnt;i++)
    {
        if(num==p)break;
        if(find(a[i].fr)!=find(a[i].to))
        join(a[i].fr,a[i].to),ans=max(ans,a[i].w),num--;
    }
    printf("%.2lf\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/Kv-Stalin/p/9592896.html