제출 #1365254

#제출 시각아이디문제언어결과실행 시간메모리
1365254HasanV11010238LOSTIKS (INOI20_lostiks)C++20
100 / 100
1546 ms265496 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 1000000000
int n;
vector<vector<int>> v;
vector<vector<int>> up;
vector<int> pr, sp, de;
void prec(int x, int p){
    de[x] = de[p] + 1;
    for (auto el : v[x]){
        if (el != p) prec(el, x);
    }
}
void dfs(int x, int p){
    pr[x] ^= pr[p];
    for (auto el : v[x]){
        if (el != p){
            dfs(el, x);
        }
    }
}
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 != p) calc(el, 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<int>()), de.assign(n + 1, 0);
    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);
            v[b].push_back(a);
        }
        else{
            v[a].push_back(b);
            v[b].push_back(a);
            al.push_back({a, b, w});
            if (sp[w] == 0) sp[w] = cc++;
            m++;
        }
    }
    prec(1, 0);
    for (int i = 0; i < m; i++){
        if (de[al[i][0]] < de[al[i][1]]) pr[al[i][1]] += (1<<i);
        else pr[al[i][0]] += (1<<i);
    }
    dfs(1, 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;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…