Submission #865187

#TimeUsernameProblemLanguageResultExecution timeMemory
865187LittleOrangeDesignated Cities (JOI19_designated_cities)C++17
39 / 100
264 ms55632 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
struct obj{
    ll to,c0,c1;// to, back
};
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    ll n,q;
    cin >> n;
    vector<vector<obj>> con(n);
    ll tot = 0;
    for(ll i = 1;i<n;i++){
        ll a,b,c,d;
        cin >> a >> b >> c >> d;a--;b--;
        con[a].push_back({b,c,d});
        con[b].push_back({a,d,c});
        tot += c+d;
    }
    ll leaf_cnt = 0;
    for(auto &o : con) if (o.size()==1) leaf_cnt++;
    cin >> q;
    bool use16 = true;
    if (n<=16&&use16){
        vector<ll> ans(n+1,tot);
        //vector<ll> ch(n+1,0);
        ll cur = tot;
        vector<vector<ll>> used(n,vector<ll>(n,0));
        function<void(ll,ll)> dfs;
        dfs = [&](ll i, ll p){
            for(obj l : con[i]){
                if (l.to!=p){
                    if (!used[i][l.to]){
                        used[i][l.to] = 1;
                        cur -= l.c1;
                    }
                    dfs(l.to,i);
                }
            }
        };
        for(ll x = 1;x<(1<<n);x++){
            cur = tot;
            for(ll i = 0;i<n;i++) for(ll j = 0;j<n;j++) used[i][j] = 0;
            ll lvl = __builtin_popcountll(x);
            for(ll i = 0;i<n;i++) if(x>>i&1) dfs(i,-1);
            //if (cur<ans[lvl]) ch[lvl] = x;
            ans[lvl] = min(ans[lvl],cur);
        }
        while(q--){
            ll e;
            cin >> e;
            cout << ans[e] << "\n";
            //for(ll i = 0;i<n;i++) cout << (ch[e]>>i&1);
            //cout << "\n";
        }
        return 0;
    }
    vector<ll> dp(n,0);
    {
        function<ll(ll,ll)> dfs;
        dfs = [&](ll i, ll p){
            ll cur = 0;
            for(obj l : con[i]){
                if (l.to!=p){
                    cur += l.c1 + dfs(l.to,i);
                }
            }
            return cur;
        };
        dp[0] = dfs(0,-1);
    }
    {
        function<void(ll,ll,ll)> dfs;
        dfs = [&](ll i, ll p, ll v){
            dp[i] = v;
            for(obj l : con[i]){
                if (l.to!=p){
                    dfs(l.to,i,v+l.c0-l.c1);
                }
            }
        };
        dfs(0,-1,dp[0]);
    }
    ll ans_1 = tot;
    for(ll i : dp) ans_1 = min(tot-i,ans_1);
    ll ans_2 = tot, tg0=-1,tg1=-1;
    vector<ll> go(n,0),ch(n,0),tg(n,0);
    {
        function<void(ll,ll)> dfs;
        dfs = [&](ll i, ll p){
            tg[i] = i;
            ll de = 0;
            for(obj l : con[i]){
                if (l.to!=p){
                    dfs(l.to,i);
                    go[i] += go[l.to]+l.c0;
                    if (go[l.to]+l.c0 - ch[l.to]>de) tg[i] = tg[l.to];
                    de = max(de,go[l.to]+l.c0 - ch[l.to]);
                }
            }
            ch[i] = go[i] - de;
        };
        dfs(0,-1);
    }
    {
        function<void(ll,ll,ll)> dfs;
        dfs = [&](ll i, ll p, ll v){
            ll w = v;
            for(obj l : con[i]){
                if (l.to!=p){
                    w += go[l.to]+l.c0;
                }
            }
            ll a = 0,b = 0,t0=-1,t1=-1;
            for(obj l : con[i]){
                if (l.to!=p){
                    dfs(l.to,i,w-(go[l.to]+l.c0)+l.c1);
                    ll cur = go[l.to]+l.c0 - ch[l.to];
                    if (cur>=a){
                        t1 = t0;
                        t0 = tg[l.to];
                        b = a;
                        a = cur;
                    }else if(cur>=b){
                        t1 = tg[l.to];
                        b = cur;
                    }
                }
            }
            if (t1!=-1){
                if (w-a-b<ans_2){
                    tg0 = t0;
                    tg1 = t1;
                }
                ans_2 = min(ans_2, w-a-b);
            }else if (p==-1){
                if (w-a<ans_2){
                    tg0 = t0;
                    tg1 = i;
                }
                ans_2 = min(ans_2, w-a);
            }
        };
        dfs(0,-1, 0);
    }
    //cout << "tgs: " << tg0+1 << " " << tg1+1 << "\n";
    vector<ll> ans(n+1,-1);
    ans[1] = ans_1;
    ans[2] = ans_2;
    for(ll i = leaf_cnt;i<=n;i++) ans[i] = 0;
    if (n<=2000){
        vector<ll> pre(n,-1), tag(n,0);
        {
            function<void(ll,ll)> dfs;
            dfs = [&](ll i, ll p){
                pre[i] = p;
                for(obj l : con[i]){
                    if (l.to!=p){
                        dfs(l.to,i);
                    }
                }
            };
            dfs(tg0,-1);
        }
        {
            ll cur = tg1;
            tag[cur] = 1;
            while(cur != tg0){
                cur = pre[cur];
                tag[cur] = 1;
            }
        }
        ll it = 3;
        while(it<=leaf_cnt){
            vector<ll> h(n,0);
            ll cur = 0, value = 0, cur_ans = 0;
            function<void(ll,ll)> dfs;
            dfs = [&](ll i, ll v){
                h[i] = tag[i]?0:v;
                for(obj l : con[i]){
                    if (l.to!=pre[i]){
                        dfs(l.to,l.c0+h[i]);
                        if (!tag[l.to]) cur_ans += l.c0;
                    }
                }
                if (h[i]>value){
                    value = h[i];
                    cur = i;
                }
            };
            dfs(tg0,0);
            ans[it-1] = cur_ans;
            tag[cur] = 1;
            while(cur != tg0){
                cur = pre[cur];
                tag[cur] = 1;
            }
            it++;
        }
    }
    while(q--){
        ll e;
        cin >> e;
        cout << ans[e] << "\n";
    }
}
#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...