제출 #1351312

#제출 시각아이디문제언어결과실행 시간메모리
1351312dabper13경주 (Race) (IOI11_race)C++20
100 / 100
160 ms40004 KiB
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using pii=pair<int,int>;

int best_path(int n, int k, int h[][2], int l[]){
    vector<vector<pair<int,int>>>adj(n);
    for(int i=0;i<n-1;i++){
        int u=h[i][0],v=h[i][1],w=l[i];
        adj[u].push_back({v,w});
        adj[v].push_back({u,w});
    }

    vector<int>tin(n),tout(n),hp(n,-1),fls(n);
    vector<ll>flw(n);
    int tt=0;

    auto dfs=[&](auto &&self,int now,int pre,ll ws,int sd)->void{
        tin[now]=tt;
        fls[tt]=sd;
        flw[tt]=ws;
        tt++;

        int mx=0,hc=-1;
        for(auto [nei,w]:adj[now]){
            if(nei==pre)continue;

            int before=tt;
            self(self,nei,now,ws+w,sd+1);
            int sub=tt-before;

            if(mx<sub){
                mx=sub;
                hc=nei;
            }
        }

        if(hc!=-1)hp[hc]=now;
        tout[now]=tt; //subtree [tin,tout)
        
    };

    dfs(dfs,0,-1,0LL,0);

    const int INF=1e9;
    int ans=INF;

    for(int leaf=0;leaf<n;leaf++){
        if(tin[leaf]+1!=tout[leaf])continue;

        unordered_map<ll,int>dp; //sw, min edge
        auto add=[&](int idx){
            ll d=flw[idx];
            int s=fls[idx];
            if(!dp.count(d))dp[d]=s;
            else dp[d]=min(dp[d],s);
        };
        auto relax=[&](int idx,int lca){
            ll need=k+2*flw[lca]-flw[idx];
            if(dp.count(need)){
                ans=min(ans,fls[idx]+dp[need]-2*fls[lca]);
            }
        };

        add(tin[leaf]);
        for(int i=leaf;hp[i]!=-1;i=hp[i]){
            int p=hp[i];

            for(auto[child,_]:adj[p]){
                if(fls[tin[child]]>fls[tin[p]] and child!=i){
                    for(int idx=tin[child];idx<tout[child];idx++){
                        relax(idx,tin[p]);
                    }
                    for(int idx=tin[child];idx<tout[child];idx++){
                        add(idx);
                    }
                }
            }
            relax(tin[p],tin[p]);
            add(tin[p]);
        }
    }

    return (ans==INF ? -1 : ans);
}

/*int main(){
    ios::sync_with_stdio(0);
    cin.tie(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...