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;
    }
  • 相关阅读:
    img标签与span一起使用不在同一条线上
    媒体查询
    section标签实现文字滚动
    js活jQuery实现动态添加、移除css/js文件
    页面中动态改变浏览器标题
    css清浮动与动态计算元素宽度
    js实现60s倒计时效果
    js与es6中获取时间戳
    JavaScript中实现小数点后保留2位
    GMT时间转换
  • 原文地址:https://www.cnblogs.com/newera/p/9127126.html
Copyright © 2011-2022 走看看