zoukankan      html  css  js  c++  java
  • 【题解】 P5021赛道修建

    【题解】P5021 赛道修建

    二分加贪心,轻松拿省一(我没有QAQ)

    题干有提示:

    输出格式:

    输出共一行,包含一个整数,表示长度最小的赛道长度的最大值。

    注意到没,最小的最大值,还要多明显?

    那么我们考虑二分。

    直接二分答案,假设我们得到了二分答案(x),我们就利用这个答案检查是否可行。考虑这样的一种办法,指定一个点为树的根,先将(dfs)放下去,每个(dfs)都要尽量将这个节点内所有的赛道合成成满足(ge x),并且贡献一条尽量长的赛道上去。假设有一个(dfs)表示自己有多于两条多出来的赛道,它们接起来不能满足条件,那么这个答案非法。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdlib>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<bitset>
    #include<ctime>
    
    using namespace std;
    #define TMP template < class ins >
    #define endl '
    '
    #define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;t++)
    #define ERP(t,a) for(register int t=head[(a)];t;t=e[t].nx)
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;t--)
    #define more(a,b) (a)=(a)>(b)?(a):(b)
    typedef long long ll;
    TMP inline ins qr(ins tag) {
        char c=getchar();
        ins x=0;
        int q=0;
        while(c<48||c>57)
            q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)
            x=x*10+c-48,c=getchar();
        return q==-1?-x:x;
    }
    const int maxn=50050;
    struct E {
        int to,w,nx;
    } e[maxn<<1];
    int head[maxn];
    ll d[maxn];
    int cnt;
    inline void add(int fr,int to,int w,bool f) {
        e[++cnt]=(E) {
            to,w,head[fr]
        };
        head[fr]=cnt;
        if(f)
            add(to,fr,w,0);
    }
    int n,m;
    ll ans;
    ll cmp;
    #define pb insert
    multiset<ll> sav[maxn];
    #define tor multiset<ll>::iterator
    
    ll dfs(int now,int last) {
        if(ans>=m)
            return 0;
        ERP(t,now) {
            if(e[t].to!=last) {
                ll temp=dfs(e[t].to,now)+e[t].w;
                if(temp>=cmp)
                    ans++;
                else
                    sav[now].pb(temp);
                if(ans>=m)
                    return 0;
            }
        }
        ll ret=0;
        if(sav[now].size()==1)
            return max(0ll,*sav[now].begin());
        while(sav[now].size()) {
            tor b=sav[now].begin();
            tor k=sav[now].lower_bound(cmp-(*b));
            if(k==sav[now].end()) {
                more(ret,*b);
                sav[now].erase(b);
                continue;
            }
            if(k==b)
                k++;
            if(k==sav[now].end()) {
                more(ret,*b);
                sav[now].erase(b);
                continue;
            }
            ans++;
            if(ans>=m)
                return 0;
            if(k==b)
                sav[now].erase(k);
            else {
                sav[now].erase(k);
                sav[now].erase(b);
            }
        }
        return ret;
    }
    
    inline bool chek(int x) {
        RP(t,1,n)
        sav[t].clear();
        cmp=x;
        ans=0;
        dfs(1,0);
        return ans>=m;
    }
    
    
    inline int eff(int rb) {
        int lb=1,mid;
        do {
            mid=(lb+rb)>>1;
            //cout<<rb<<' '<<mid<<' '<<lb<<endl;
            if(chek(mid))
                lb=mid+1;
            else
                rb=mid-1;
        } while(lb<=rb);
        return rb;
    }
    
    
    
    void predfs(int now,int last,int w) {
        d[now]=d[last]+w;
        ERP(t,now)
        if(e[t].to!=last)
            predfs(e[t].to,now,e[t].w);
    }
    int t1,t2,t3;
    const int inf=0x3f3f3f3f;
    inline void init() {
        n=qr(1);
        m=qr(1);
        RP(t,1,n-1) {
            t1=qr(1);
            t2=qr(1);
            t3=qr(1);
            add(t1,t2,t3,1);
        }
        predfs(1,0,0);
        ll sav=0,rem=-inf;
        RP(t,1,n)
        if(d[t]>rem)
            sav=t,rem=d[t];
        predfs(sav,0,0);
        sav=0,rem=-inf;
        RP(t,1,n)
        if(d[t]>rem)
            sav=t,rem=d[t];
        cout<<eff(rem)<<endl;
    }
    
    
    
    signed main() {
    #ifndef ONLINE_JUDGE
        freopen("testdata.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        init();
        return 0;
    }
    
    
  • 相关阅读:
    Spring Cloud的小改进(五)
    国内最火的10款Java开源项目,都是国人开发,CMS居多
    创建服务的注册与发现 Eureka (四)
    Eureka的的概述(三)
    sourcetree 跳过首次登录
    基于IDEA工具 lombok 的使用
    面试总结
    Spring Cloud的概述(二)
    微服务的概述(一)
    原子性 CAS算法
  • 原文地址:https://www.cnblogs.com/winlere/p/10335691.html
Copyright © 2011-2022 走看看