zoukankan      html  css  js  c++  java
  • [BZOJ 2429] 聪明的猴子

    Link:

    BZOJ 2429 传送门

    Solution:

    可将题意转化为求使原图连通的子图中最长边的最小值

    那么立即联想到求最小生成树的Kruscal算法:每次选择最短的边加入答案集合

    最小生成树的最长边就是要求的值

    正确性是显然的(边权是从小到大选取的),而这也是最小生成树的推论之一:

    对于任意一个连通图,图中A点走到B点的所有路径中,最长的边最小值是肯定出现在最小生成树中A到B的路径上

    最后计算结果即可

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef pair<int,int> P;
    #define X first
    #define Y second
    const int MAXN=1e3+10;
    P dat[MAXN];
    int n,m,jump[MAXN],f[MAXN],cnt=0,tot=0,mx=0,res=0;
    struct edge{int x,y,v;}e[MAXN*MAXN];
    
    bool cmp(edge a,edge b){return a.v<b.v;}
    int ufs_find(int x){return (f[x]==x)?x:f[x]=ufs_find(f[x]);}
    
    int main()
    {
        scanf("%d",&m);
        for(int i=1;i<=m;i++) scanf("%d",&jump[i]);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&dat[i].X,&dat[i].Y),f[i]=i;
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++) //只记录平方值防止精度问题
                e[++cnt]=edge{i,j,(dat[i].X-dat[j].X)*(dat[i].X-dat[j].X)+(dat[i].Y-dat[j].Y)*(dat[i].Y-dat[j].Y)};
        sort(e+1,e+cnt+1,cmp);
        
        for(int i=1;i<=cnt;i++)
        {
            int posx=ufs_find(e[i].x),posy=ufs_find(e[i].y);
            if(posx!=posy)
            {
                f[posx]=posy;tot++;
                if(tot==n-1){mx=e[i].v;break;}
            }
        }
        for(int i=1;i<=m;i++)
            if(jump[i]*jump[i]>=mx) res++;
        printf("%d",res);
        return 0;
    }
  • 相关阅读:
    webFlux&Reactor
    Docker镜像使用
    Docker的使用
    Docker的容器使用
    为什么样本方差除以(n-1)而不是n ?(自由度)
    机器学习(一)—— 线性回归
    线性、逻辑回归的java实现
    整合多个网络的拓扑结构并降维(Mashup)
    KS检验统计量的扩展应用(CMap)
    p-value
  • 原文地址:https://www.cnblogs.com/newera/p/9127126.html
Copyright © 2011-2022 走看看