noip 2018 day1 T3 赛道修建 贪心 + 树上问题 + multiset

Code:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;

#define maxn 50008
#define MAXR 500000001
#define ll int 

multiset <ll> S[maxn];
multiset <ll> :: iterator it;
int head[maxn], to[maxn << 1], nex[maxn << 1], val[maxn << 1];
int cnt,n, m, edges;
ll mid; 

void setIO(string a){
    freopen((a+".in").c_str(),"r",stdin); 
}

void addedge(int u,int v,int c){
    nex[++edges] = head[u], head[u] = edges, to[edges] = v, val[edges] = c;
}

void read(){
    scanf("%d%d",&n,&m);
    for(int i = 1;i < n;++i){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
    }
}

ll dfs(int u,int fa){
    S[u].clear();
    for(int v = head[u]; v ; v = nex[v]){
        if(to[v] == fa) continue;
        ll t = dfs(to[v], u) + val[v];
        if(t >= mid)  ++cnt;
        else S[u].insert(t); 
    }

    ll MAX = 0;

    while(!S[u].empty()){
        if(S[u].size() == 1)  return max(MAX, *S[u].begin());
        it = S[u].lower_bound(mid - *S[u].begin());
        if(it == S[u].begin() && S[u].count(*it) == 1) it++;
        if(it == S[u].end()){
            MAX = max(MAX, *S[u].begin()); 
            S[u].erase(S[u].find(*S[u].begin()));
        } else {
            ++cnt ;
            S[u].erase(S[u].find(*it));
            S[u].erase(S[u].find(*S[u].begin()));
        } 
    }

    return MAX;
}

bool check(){
    cnt = 0;
    dfs(1, 0);
    if(cnt >= m) return true;
    return false;
}

void solve(){
    ll l = 0, r = MAXR, ans = 0;
    while(l <= r){
        mid = (l + r) >> 1;
        if(check()) ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    printf("%lld", ans);
}

void shut(){
    fclose(stdin);
}

int main(){
    //setIO("input");
    read();
    solve();
    shut();
    return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/9973164.html