Submission #1364163

#TimeUsernameProblemLanguageResultExecution timeMemory
1364163mrasool1665LOSTIKS (INOI20_lostiks)C++20
100 / 100
1393 ms458256 KiB
//MRasool Kheyri
//Iran -> khorasan -> ferdows -> baghestan!
//10/2/1405
//felan atash bas shode
#include <bits/stdc++.h>
using namespace std ;
typedef int ll ;
#pragma GCC optimize("O3","unroll-loops","Ofast")
#define el '\n'
#define lid id<<1
#define rid lid|1
#define mid (l+r)/2
const ll maxn = 1e6 + 100 ;
const ll maxk = 20+1 ;
const ll mod = 1e9 + 7 ;
const ll oo = 1e9 + 10 ;
ll n , m , S , E , h[maxn] , good[maxn] , g[maxn] , st[maxn] , fi[maxn] , ind[maxn] , msk[maxn] , key[maxn] ;
ll spt[2*maxn][maxk] , dp[130][1<<maxk] , h2[maxn] , anc[maxn][maxk] , felan[maxn] ;
ll nazdik[maxn] , fasele[maxn] ;
pair<ll,ll> sar[maxn] ;
vector<ll> adj[maxn] ;
vector<pair<ll,pair<ll,ll>>> adj2[maxn] ;
vector<pair<pair<ll,ll>,ll>> edge ;
vector<ll> tour ;
vector<ll> vec[maxn] ;
void dfs1(ll u , ll p){
    st[u] = tour.size() ;
    tour.push_back(u) ;
    for(auto v : adj[u]){
        if(v == p){continue;}
        h[v] = h[u]+1 ;
        dfs1(v,u) ;
        tour.push_back(u) ;
    }
    fi[u] = tour.size() ;
    return ;
}
ll get_lca(ll u , ll v){
    ll l = min(st[u],st[v]) , r = max(fi[u],fi[v]) ;
    ll lg = 31-__builtin_clz(r-l) ;
    return h[spt[l][lg]] < h[spt[r-(1<<lg)][lg]] ? spt[l][lg] : spt[r-(1<<lg)][lg] ;
}
vector<ll> vertex ;
bool cmp(ll u , ll v){
    return st[u] < st[v] ;
}
void build(){
    sort(vertex.begin(),vertex.end(),cmp) ;
    for(ll i = 0 ; i < vertex.size()-1 ; i++){
        ll u = vertex[i] , v = vertex[i+1] ;
        ll lca = get_lca(u,v) ;
        if(good[lca]){continue;}
        good[lca] = 1 ;
        vertex.push_back(lca) ;
    }
    vector<pair<ll,ll>> tim ;
    for(auto u : vertex){
        tim.push_back({st[u],u}) ;
        tim.push_back({fi[u],u}) ;
    }
    sort(tim.begin(),tim.end()) ;
    vector<ll> stc ;
    for(ll i = 0 ; i < tim.size() ; i++){
        ll u = tim[i].second ;
        if(stc.size()){
            if(stc.back() == u){
                stc.pop_back() ;
                continue ;
            }
            adj2[stc.back()].push_back({u,{h[u]-h[stc.back()],g[u]}}) ;
            adj2[u].push_back({stc.back(),{h[u]-h[stc.back()],g[u]}}) ;
        }
        stc.push_back(u) ;
    }
    return ;
}
void dfs2(ll u , ll p){
    for(auto pari : adj2[u]){
        ll v = pari.first ;
        if(v == p){continue;}
        h2[v] = h2[u]+1 ;
        anc[v][0] = u ;
        dfs2(v,u) ;
    }
    return ;
}
ll LCA(ll u , ll v){
    if(h2[u] < h2[v]){swap(u,v);}
    for(ll bit = maxk-1 ; bit >= 0 ; bit--){
        if(h2[u]-(1<<bit) < h2[v]){continue;}
        u = anc[u][bit] ;
    }
    if(u == v){return u;}
    for(ll bit = maxk-1 ; bit >= 0 ; bit--){
        if(h2[u] < (1<<bit) || anc[u][bit] == anc[v][bit]){continue;}
        u = anc[u][bit] ;
        v = anc[v][bit] ;
    }
    return anc[u][0] ;
}
ll dis(ll u , ll v){
    return h[u]+h[v]-2*(h[LCA(u,v)]) ;
}
void solve(){
    m = 0 ;
    cin>>n ;
    cin>>S>>E ;
    S-- , E-- ;
    for(ll i = 0 ; i < n-1 ; i++){
        ll u , v , w ;
        cin>>u>>v>>w ;
        u-- , v-- , w-- ;
        adj[u].push_back(v) ;
        adj[v].push_back(u) ;
        if(w != -1){
            edge.push_back({{u,v},m}) ;
            vec[w].push_back(m) ;
            sar[m] = {u,v} ;
            key[m] = w ;
            m++ ;
        }
    }
    dfs1(S,-1) ;
    for(ll i = 0 ; i < tour.size() ; i++){
        spt[i][0] = tour[i] ;
    }
    for(ll x = 1 ; x < maxk ; x++){
        for(ll i = 0 ; i < tour.size() ; i++){
            if(tour.size() < i+(1<<x)){continue;}
            spt[i][x] = h[spt[i][x-1]] < h[spt[i+(1<<(x-1))][x-1]] ? spt[i][x-1] : spt[i+(1<<(x-1))][x-1] ;
        }
    }
    fill(g,g+n,-1) ;
    good[S] = 1 ;
    vertex.push_back(S) ;
    if(!good[E]){
        good[E] = 1 ;
        vertex.push_back(E) ;
    }
    for(ll _ = 0 ; _ < edge.size() ; _++){
        ll u = edge[_].first.first , v = edge[_].first.second , i = edge[_].second ;
        ll w = key[i] ;
        if(h[u] < h[v]){swap(u,v);}
        if(!good[u]){
            good[u] = 1 ;
            vertex.push_back(u) ;
        }
        if(!good[w]){
            good[w] = 1 ;
            vertex.push_back(w) ;
        }
        if(!good[v]){
            good[v] = 1 ;
            vertex.push_back(v) ;
        }
        g[u] = i ;
    }
    build() ;
    dfs2(S,-1) ;
    for(ll x = 1 ; x < maxk ; x++){
        for(auto u : vertex){
            if(h2[u] < (1<<x)){continue;}
            anc[u][x] = anc[anc[u][x-1]][x-1] ;
        }
    }
    for(ll i = 0 ; i < vertex.size() ; i++){
        ind[vertex[i]] = i ;
    }
    for(auto i : vertex){
        for(auto k : vec[i]){
            ll u = sar[k].first , v = sar[k].second ;
            if(dis(i,u) > dis(i,v)){swap(u,v);}
            nazdik[k] = u ;
            ll cur = i ;
            while(cur != u){
                for(auto pari : adj2[cur]){
                    ll v = pari.first , w = pari.second.first , b = pari.second.second ;
                    if(dis(cur,u) <= dis(v,u)){continue;}
                    if(b != -1){
                        msk[k] += 1<<b ;
                    }
                    fasele[k] += w ;
                    cur = v ;
                    break ;
                }
            }
        }
    }
    priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> pq ;
    for(ll mask = 0 ; mask < (1<<m) ; mask++){
        for(auto u : vertex){
            dp[ind[u]][mask] = oo ;
            felan[u] = oo ;
        }
        pq.push({0,E}) ;
        ll bil = mask ;
        while(bil){
            ll k = bil&(-bil) ;
            bil -= k ;
            k = 31-__builtin_clz(k) ;
            ll i = key[k] ;
            if((msk[k]&((1<<m)-1-mask)) == msk[k]){
                ll u = nazdik[k] ;
                pq.push({min(oo,fasele[k]+dp[ind[u]][mask^(1<<k)]),i}) ;
            }
        }
        ll cnt = 0 ;
        while(pq.size()){
            if(cnt == vertex.size()){break;}
            cnt++ ;
            ll u = pq.top().second , w = pq.top().first ;
            pq.pop() ;
            if(dp[ind[u]][mask] != oo || w == oo){continue;}
            dp[ind[u]][mask] = w ;
            for(auto pari : adj2[u]){
                ll v = pari.first , W = pari.second.first , b = pari.second.second ;
                if(((mask>>b)&1) || dp[ind[v]][mask] != oo || felan[v] <= (w+W)){continue;}
                pq.push({min(oo,w+W),v}) ;
                felan[v] = w+W ;
            }
        }
        while(pq.size()){
            pq.pop() ;
        }
    }
    if(dp[ind[S]][(1<<m)-1] >= oo){
        cout<<-1<<el;
        return ;
    }
    cout<<dp[ind[S]][(1<<m)-1]<<el ;
    return ;
}
int main(){
    ios_base::sync_with_stdio(0) , cin.tie(nullptr) , cout.tie(nullptr) ;
    ll t = 1 ;
    //cin>>t ;
    while(t--){
        solve() ;
    }
    return 0 ;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...