• 赛道修建——二分答案


    题目链接:https://www.luogu.com.cn/problem/P5021

    分析:

    题目大意就不讲了。此题很多人说一眼就知道是二分,那就当我也这么认为吧。此题思考的关键在于不能重边。先设二分的值为k,我们思考一个状态:此时搜到一个点,暂时不考虑下面回溯上来的值,当该值加上其对应的边权大于等于k,则直接统计到答案里,剩余的不满k的值先存起来。我们知道剩余的这些边中还是会存在满足大于等于k的情况,只要任意两条加在一起大于等于k就可以计入答案。(记住这里要用贪心,即对于每条边选择可行方案里最小的)接下来同样按着贪心,选择一条剩余边里最大的一条回溯上去,该值即上文回溯上来的值。看不懂的看代码食用更佳哦!

    补充:代码里用到了set库里的multiset,这里使用能更佳方便地实现代码,不会的建议了解一下。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<set>
    using namespace std;
    #define int long long
    #define R register
    inline int read(){
        int a=0,b=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')b=-1;c=getchar();}
        while(isdigit(c)){a=a*10+c-'0';c=getchar();}
        return a*b;
    }
    multiset<int>::iterator it;
    const int N=5e4+50,M=2e5+50;
    int n,m,tot,cnt,h[N],ver[M],nx[M],ed[M],ave,l,r,ans;
    void add(int u,int v,int z){
        ver[++tot]=v;ed[tot]=z;
        nx[tot]=h[u];h[u]=tot;
    }
    int dfs(int x,int fa,int kkk){
        multiset<int>s;
        for(R int i=h[x],dis;i;i=nx[i]){
            int v=ver[i],z=ed[i];
            if(v==fa)continue;
            dis=z+dfs(v,x,kkk);
            if(dis>=kkk)cnt++;
            else s.insert(dis);
        }
        int maxn=0;
        while(s.size()){
            int p=*s.begin();
            s.erase(s.begin());
            it=s.lower_bound(kkk-p);
            if(it!=s.end()){
                cnt++;
                s.erase(it);
            }
            else{
                maxn=max(maxn,p);
            }
        }
        return maxn;
    }
    bool check(int kkk){
        cnt=0;
        dfs(1,0,kkk);
        if(cnt>=m)return true;
        else return false;
    }
    signed main(){
        n=read();m=read();
        int u,v,z;
        for(R int i=1;i<n;i++){
            u=read();v=read();z=read();
            add(u,v,z);add(v,u,z);
            ave+=z;
        }
        ave/=m;
        l=1,r=ave;
        int mid;
        while(l<=r){
            mid=(l+r)>>1;
            if(check(mid))ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    ubuntu下pip的安装和使用
    跨域总结
    本地存储小结
    SVN
    appium整理文档
    appium python andiroid自动化文档整理笔记
    Python 接口测试(二)
    Python 接口测试(一)
    Python 接口测试(四)
    Python 接口测试(三)
  • 原文地址:https://www.cnblogs.com/zjy1412/p/13517689.html
Copyright © 2020-2023  润新知