Submission #1292915

#TimeUsernameProblemLanguageResultExecution timeMemory
1292915BuiDucManh123LOSTIKS (INOI20_lostiks)C++20
100 / 100
1956 ms411972 KiB
#include <bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define taskname ""
const int mod = 1e9+7;
using namespace std;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
#define int ll
const int inf = 2e9;
const int lg = 20;
int dis1[49][49], dis2[49], depth[1000009], sum[1000009], door[29], f[29][1000009], trace[1000009], dp[23][(1 << 21) + 5];
vector<pii> g[1000009];
void dfs(int u, int p){
    for(pii v : g[u]){
        if(v.fi == p) continue;
        f[0][v.fi] = u;
        sum[v.fi] = sum[u];
        if(v.se){
            door[trace[v.se]] = u;
            sum[v.fi] |= (1 << trace[v.se]);
        }
        depth[v.fi] = depth[u] + 1;
        dfs(v.fi, u);
    }
}
int lca(int u, int v){
    if(depth[u] < depth[v]) swap(u, v);
    for(int i = lg - 1; i >= 0; i--){
        if(depth[u] - (1 << i) >= depth[v]){
            u = f[i][u];
        }
    }
    if(u == v) return u;
    for(int i = lg - 1; i >= 0; i--){
        if(f[i][u] != f[i][v]){
            u = f[i][u];
            v = f[i][v];
        }
    }
    return f[0][u];
}
void solve(){
    int n, s, t;
    cin >> n >> s >> t;
    vector<int> key;
    key.pb(0);
    int cnt = 0;
    for(int i = 1; i < n; i++){
        int u, v, w;
        cin >> u >> v >> w;
        int now = 0;
        if(w != 0){
            cnt++;
            key.pb(w);
            now = cnt;
        }
        g[u].pb({v, now});
        g[v].pb({u, now});
    }
    int sz = cnt + 1;
    for(int i = 0; i < sz; i++){
        door[i] = -1;
    }
    key[0] = s;
    door[0] = s;
    f[0][s] = s;
    vector<int> st;
    st.pb(s);
    while(!st.empty()){
        int u = st.back();
        st.pop_back();
        for(pii e: g[u]){
            int v = e.fi;
            if(v == f[0][u]) continue;
            f[0][v] = u;
            depth[v] = depth[u] + 1;
            sum[v] = sum[u];
            if(e.se != 0){
                int k = e.se;
                door[k] = u;
                sum[v] |= (1 << k);
            }
            st.pb(v);
        }
    }
    for(int k = 1; k < sz; k++){
        if(door[k] == -1){
            cout << -1;
            return;
        }
    }
    for(int i = 1; i < lg; i++){
        for(int j = 1; j <= n; j++){
            f[i][j] = f[i - 1][f[i - 1][j]];
        }
    }
    for(int i = 0; i < sz; i++){
        for(int j = 0; j < (1 << sz); j++){
            dp[i][j] = inf;
        }
    }
    for(int i = 0; i < sz; i++){
        int u = key[i];
        int v = door[i];
        int w = lca(u, v);
        dis2[i] = depth[u] + depth[v] - 2 * depth[w];
        for(int j = 0; j < sz; j++){
            int vv = key[j];
            int ww = lca(v, vv);
            dis1[i][j] = depth[v] + depth[vv] - 2 * depth[ww];
        }
    }
    /*
    for(int i = 0; i < sz; i++){
        cout << key[i] << " " << door[i] << " " << dis2[i] << "\n";
    }
    */
    /*
    for(int i = 0; i < sz; i++){
        cout << key[i] << "\n";
    }
    */
    dp[0][1] = 0;
    for(int mask = 1; mask < (1 << sz); mask++){
        for(int i = 0; i < sz; i++){
            for(int j = 1; j < sz; j++){
                if(!((mask >> j) & 1)){
                    int u = key[j];
                    int v = door[j];
                    int path1 = sum[door[i]] ^ sum[u];
                    int path2 = sum[v] ^ sum[u];
                    if((mask & path1) == path1 && (mask & path2) == path2){
                            /*
                        if((mask | (1 << j)) == 5 && j == 2 && i == 0){
                            cout << dp[i][mask] << " " << dis1[i][j] << " " << dis2[j] << "\n";
                                                     }
                                                     */
                        dp[j][mask | (1 << j)] = min(dp[j][mask | (1 << j)], dp[i][mask] + dis1[i][j] + dis2[j]);
                    }
                }
            }
        }
    }
    //cout << dp[2][5];
    int ans = inf;
    for(int mask = 0; mask < (1 << sz); mask++){
        for(int i = 0; i < sz; i++){
            int u = door[i];
            int path = sum[u] ^ sum[t];
            int w = lca(u, t);
            if((mask & path) == path){
                ans = min(ans, dp[i][mask] + depth[u] + depth[t] - 2 * depth[w]);
            }
        }
    }
    if(ans == inf){
        cout << -1;
        return;
    }
    cout << ans;
}
signed main() {
    if (fopen(taskname".inp","r")) {
        freopen(taskname".inp","r",stdin);
        freopen(taskname".out","w",stdout);
    }
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int test = 1;
    //cin >> test;
    while(test--){
        solve();
    }
    return 0;
}


Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:167:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  167 |         freopen(taskname".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:168:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  168 |         freopen(taskname".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...