码迷,mamicode.com
首页 > 其他好文 > 详细

北极通讯网络

时间:2019-11-04 22:03:29      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:namespace   name   复杂   class   sort   分割   最大的   ==   比较   

https://loj.ac/problem/10065

题目描述

??给出\(n\)个村庄的位置,求如何选取\(k\)个村庄使得最大的\(d\)值最小。

思路

??正向思维比较复杂,我们考虑逆向思维,当最大的\(d\)值为多少时恰好需要\(k\)个卫星设备。这样就转化为将可以用无线电通信的村庄连边,图中有\(k\)个连通支。或者说将图中所有村庄两两连边,去掉大于\(d\)的边后图中有\(k\)个连通支。

??定理:如果去掉所有权值大于\(d\)的边后,最小生成树被分割为\(k\)个连通支,则图也被分割为\(k\)个连通支。

??证明:假设原图被分为\(cnt\)个连通支\((cnt!=k)\),显然只可能\(cnt<k\)。那么在图的一个连通支中必定被分为\(2\)部分,设为\(T1\)\(T2\),并且在原图中有边相连,而在最小生成树中有一条连接被断开,因此在原图中有一条连接\(T1、T2\)的边而小于最小生成树中连接\(T1、T2\)的边,那么可以将这条边加入最小生成树,得到一棵更小的生成树,显然不成立,由此定理成立。

??而要将最小生成树恰好分成\(k\)个连通支,\(d\)值即为最小生成树中的第\(k\)长边。我们考虑\(Kruskal\)的过程,每次选出一条连接两个未连通的连通支的边,因此每一条边都连通着两个连通支,所以删去\(k\)条边就形成\(k\)个连通支。

代码

#include <bits/stdc++.h>
using namespace std;
struct aa
{
    int u,v;
    double w;
}a[250005];
struct Node
{
    int x,y;
}p[600];
int fa[600];
double v[600];
int sqr(int x)
{
    return x*x;
}
bool cmp(aa x,aa y)
{
    return x.w<y.w;
}
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main() 
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&p[i].x,&p[i].y);
        fa[i]=i;
    }
    int cnt=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        if(i^j)
        {
            a[++cnt].u=i;a[cnt].v=j;
            a[cnt].w=sqrt(sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y));
        }
    sort(a+1,a+cnt+1,cmp);
//    for(int i=1;i<=cnt;i++)
//        printf("%.2lf\n",a[i].w);
    int j=0;
    for(int i=1;i<=cnt;i++)
    {
        int fx=find(a[i].u),fy=find(a[i].v);
        if(fx!=fy)
        {
            fa[fx]=fy;
            v[++j]=a[i].w;
            if(j==n-1)break ;
        }
    }
//    for(int i=1;i<n;i++)
//        printf("%.2lf\n",v[i]);
    printf("%.2lf",v[n-k]);
    return 0;
}

北极通讯网络

标签:namespace   name   复杂   class   sort   分割   最大的   ==   比较   

原文地址:https://www.cnblogs.com/fangbozhen/p/11794797.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!