Submission #1365249

#TimeUsernameProblemLanguageResultExecution timeMemory
1365249HasanV11010238LOSTIKS (INOI20_lostiks)C++20
59 / 100
2101 ms253360 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 1000000000
int n;
vector<vector<vector<int>>> v;
vector<vector<int>> up;
vector<int> pr, sp;
void dfs(int x, int p, int val){
    pr[x] = (pr[p] ^ val);
    for (auto &el : v[x]){
        if (el[0] != p){
            dfs(el[0], x, el[1]);
        }
    }
}
void calc(int x, int p, int wh){
    if (p != 0) up[wh][x] = up[wh][p] + 1;
    for (auto &el : v[x]){
        if (el[0] != p) calc(el[0], x, wh);
    }
}
int dist(int a, int b){
    if (sp[b] != 0) swap(a, b);
    return up[sp[a]][b];
}
int check(int a, int b, int mask){
    return (((pr[a] ^ pr[b]) | mask) == mask);
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int s, t, a, b, w, m = 0, cc = 3;
    cin>>n;
    cin>>s>>t;
    v.assign(n + 1, vector<vector<int>>());
    up.assign(23, vector<int>(n + 1, 0));
    pr.assign(n + 1, 0), sp.assign(n + 1, 0);
    sp[s] = 1; sp[t] = 2;
    vector<vector<int>> al;
    for (int i = 0; i < n - 1; i++){
        cin>>a>>b>>w;
        if (w == 0){
            v[a].push_back({b, w});
            v[b].push_back({a, w});
        }
        else{
            v[a].push_back({b, (1<<m)});
            v[b].push_back({a, (1<<m)});
            al.push_back({a, b, w});
            if (sp[w] == 0) sp[w] = cc++;
            m++;
        }
    }
    dfs(1, 0, 0);
    for (int i = 1; i <= n; i++){
        if (sp[i] == 0) continue;
        calc(i, 0, sp[i]);
    }
    int ans = INF;
    if (check(s, t, 0) == 1) ans = dist(s, t);
    int ti = (1<<m);
    vector<vector<int>> dp(ti, vector<int>(m, INF));
    vector<int> wh(m + 1, 0);
    for (int i = 0; i < m; i++){
        if (check(al[i][2], s, 0) == 1) dp[(1<<i)][i] = dist(al[i][2], s);
        if (dist(al[i][2], al[i][0]) < dist(al[i][2], al[i][1])){
            wh[i] = al[i][0];
        }
        else wh[i] = al[i][1];
    }
    vector<int> us(m + 1, 0), nus(m + 1, 0);
    for (int i = 1; i < ti; i++){
        int c0 = 0, c1 = 0, el = 0, val = 0;
        for (int j = 0; j < m; j++){
            int val = (i & (1<<j));
            if (val != 0) us[c0++] = j;
            else nus[c1++] = j;
        }
        for (int j = 0; j < c0; j++){
            el = us[j];
            int cur = wh[el];
            if (check(cur, al[el][2], i) == 0){
                dp[i][el] = INF;
                continue;
            }
            else dp[i][el] += dist(cur, al[el][2]);
            if (check(cur, t, i) == 1) ans = min(ans, dp[i][el] + dist(cur, t));
            for (int k = 0; k < c1; k++){
                val = nus[k];
                int to = (i | (1<<val));
                if (check(cur, al[val][2], i) == 1){
                    dp[to][val] = min(dp[to][val], dp[i][el] + dist(al[val][2], cur));
                }
            }
        }
    }
    if (ans >= INF) cout<<-1;
    else cout<<ans;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...