제출 #1350521

#제출 시각아이디문제언어결과실행 시간메모리
1350521whtthParkovi (COCI22_parkovi)C++20
110 / 110
1260 ms201360 KiB
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;

int n, k, x, y, w, t = 0, up[20][200001], child[200001], par[200001], h[200001], st[21][400001], f[200001];
bool ok[200001], del[200001];
long long cnt, d[200001], sum[20][200001], best[200001], S;

vector<pair<int, int>> ke[200001];
vector<pair<long long, int>> a;
vector<int> ans;
vector<pair<int, long long>> path[200001];

void dfs(int u, int p){
    for(auto [v, w] : ke[u]){
        if(v == p) continue;
        up[0][v] = u;
        sum[0][v] = w;
        h[v] = h[u] + 1;
        for(int i = 1; i <= __lg(n); i++){
            up[i][v] = up[i - 1][up[i - 1][v]];
            sum[i][v] = sum[i - 1][v] + sum[i - 1][up[i - 1][v]];
        }
        d[v] = d[u] + w;
        dfs(v, u);
    }
}

void dfs2(int u, int p){
    f[u] = ++t;
    st[0][t] = u;
    for(auto [v, w] : ke[u]){
        if(v == p) continue;
        dfs2(v, u);
        t++;
        st[0][t] = u;
    }
}

void build2(){
    for(int i = 1; i <= __lg(t); i++){
        for(int j = 1; j <= t - (1 << i) + 1; j++){
            x = st[i - 1][j];
            y = st[i - 1][j + (1 << (i - 1))];
            if(h[x] < h[y]) st[i][j] = x;
            else st[i][j] = y;
        }
    }
}

int lca(int l, int r){
    if(l > r) swap(l, r);
    int k = __lg(r - l + 1);
    x = st[k][l];
    y = st[k][r - (1 << k) + 1];
    if(h[x] < h[y]) return x;
    else return y;
}

long long dist(int u, int v){
    return d[u] + d[v] - 2 * d[lca(f[u], f[v])];
}

void countchild(int u, int p){
    child[u] = 1;
    for(auto [v, w] : ke[u]){
        if(v == p || del[v]) continue;
        countchild(v, u);
        child[u] += child[v];
    }
}

int centroid(int u, int p, int n){
    for(auto [v, w] : ke[u]){
        if(v != p && !del[v] && child[v] > n / 2) return centroid(v, u, n);
    }
    return u;
}

void collect(int u, int p, int cen, long long dist0){
    path[u].push_back({cen, dist0});
    for(auto [v, w] : ke[u]){
        if(v == p || del[v]) continue;
        collect(v, u, cen, dist0 + w);
    }
}

int build(int u){
    countchild(u, 0);
    int n = child[u];
    int root = centroid(u, 0, n);
    del[root] = true;

    collect(root, 0, root, 0);

    for(auto [v, w] : ke[root]){
        if(!del[v]){
            int f = build(v);
            par[f] = root;
        }
    }
    return root;
}

int dat(int u){
    long long cnt = 0;
    for(int i = __lg(n); i >= 0; i--){
        if(cnt + sum[i][u] <= S){
            cnt += sum[i][u];
            u = up[i][u];
            if(u <= 1) return 1;
        }
    }
    return u;
}

inline bool phu(int u){
    for(auto [c, d0] : path[u]){
        if(best[c] + d0 <= S) return true;
    }
    return false;
}

inline void upd(int u){
    for(auto [c, d0] : path[u]){
        best[c] = min(best[c], d0);
    }
}

bool check(long long pp){
    S = pp;
    fill(best + 1, best + n + 1, (long long)4e18);
    vector<int> now;
    for(auto [ff, g] : a){
        if(!phu(g)){
            int r = dat(g);
            now.push_back(r);
            upd(r);
            if((int)now.size() > k) return false;
        }
    }
    ans = now;
    return true;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(nullptr);

    cin >> n >> k;
    for(int i = 1; i < n; i++){
        cin >> x >> y >> w;
        ke[x].push_back({y, w});
        ke[y].push_back({x, w});
    }

    dfs(1, 0);
    dfs2(1, 0);
    build2();
    build(1);

    for(int i = 1; i <= n; i++) a.push_back({d[i], i});
    sort(a.begin(), a.end(), greater<pair<long long, int>>());

    long long vt = -1, l = 1, r = 2e14, mid;
    while(l <= r){
        mid = (l + r) / 2;
        if(check(mid)){
            vt = mid;
            r = mid - 1;
        }else l = mid + 1;
    }

    cout << vt << "\n";
    for(int v : ans) ok[v] = true;

    int m = (int)ans.size();
    vector<int> nans;
    for(int i = 1; i <= n; i++){
        if(ok[i]) nans.push_back(i);
        else if(m < k){
            m++;
            nans.push_back(i);
        }
    }

    for(int j = 0; j < (int)nans.size() - 1; j++) cout << nans[j] << " ";
    cout << nans.back();
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...