제출 #1327704

#제출 시각아이디문제언어결과실행 시간메모리
1327704spetrDesignated Cities (JOI19_designated_cities)C++20
100 / 100
719 ms105072 KiB
#include <bits/stdc++.h>

using namespace std;

#define ll long long
const ll mmod = 998244353;  
#define vl vector<long long>
#define vll vector<vector<long long>>
#define pl pair<long long, long long>
#define vb vector<bool>

vector<vector<vl>> graf;
ll s = 0;
ll optimum = 2e18;
ll root = 0;
vl ans;
vector<pl> maximum;
vl cost; 
ll ans2 = 2e18; 
pl listy;
unordered_set<ll> path;
vl paths;

void dfs1(ll v, ll p){
    for(auto x : graf[v]){
        if (x[0] != p){
            s += x[1];
            dfs1(x[0], v);
        }
    }
}

void dfs2(ll v, ll p, ll sub){
    cost[v] = sub;
    if (sub < optimum){
        optimum = sub;
        root = v;
    }
    for(auto x : graf[v]){
        if (x[0] != p){
            dfs2(x[0], v, sub - x[1] + x[2]);
        }
    }
}

pl dfs3(ll v, ll p){
    vector<pl> bests {{0, v},{0,v}};
    
    ll list = v;
    for(auto x : graf[v]){
        if (x[0] != p){
            pl sub = dfs3(x[0], v); 
            ll down = sub.first + x[1];
            list = sub.second;
            bests.push_back({down, list});
        }
    }
    sort(bests.begin(), bests.end()); reverse(bests.begin(), bests.end());

    ll candidate = cost[v] - bests[0].first - bests[1].first;
    if (candidate < ans2) {
        ans2 = candidate;
        listy = {bests[0].second, bests[1].second};
    }
    
    return bests[0];
}

void bfs(){
    ll n = cost.size();
    vl ancestor(n ,-1);
    queue<ll> q;
    q.push(listy.first);
    ancestor[listy.first] = -2;
    while (!q.empty()){
        ll p = q.front(); q.pop();
        if (p == listy.second){
            break;
        }
        for (auto x : graf[p]){
            if (ancestor[x[0]] == -1){
                ancestor[x[0]] = p;
                q.push(x[0]);
            }
        }
    } 
    ll pos = listy.second;
    while (pos != -2){
        path.insert(pos);
        pos = ancestor[pos];
    }
}

ll dfs4 (ll v, ll p){
    vl subs {0};
    for (auto x : graf[v]){
        if (x[0] != p){
            subs.push_back(dfs4(x[0], v) + x[1]);
        }
    }
    sort(subs.begin(), subs.end()); reverse(subs.begin(), subs.end());
    for (ll i = 1; i < subs.size(); i++){
        paths.push_back(subs[i]);
    }
    auto it = path.find(v);
    if (it != path.end()){
        paths.push_back(subs[0]);
        return -2e18;
    }
    return subs[0];
    
}

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

    ll n;
    cin >> n;
    graf.resize(n);
    ans.resize(n+10, 0);
    cost.resize(n, 0);
    for (ll i = 0; i < n-1; i++){
        ll a,b,c,d;
        cin >>a >>b  >>c >>d;
        a--; b--;
        graf[a].push_back({b,c, d});
        graf[b].push_back({a,d, c});
    }

    dfs1(0, -1);
    dfs2(0, -1, s);

    maximum.resize(n, {0,0});
    ans[1] = optimum;

    dfs3(0, -1);
    ans[2] = ans2;

    bfs();

    dfs4(listy.first, -1);

    sort(paths.begin(), paths.end()); reverse(paths.begin(), paths.end());
    for (ll i = 3; i <= n; i++){
        ans[i] = ans[i-1] - max(paths[i-3], 0ll);
    }

    ll q;
    cin >>q;
    for (ll i = 0; i < q; i++){
        ll e;
        cin >> e;
        cout << ans[e] <<"\n";
    }

    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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...