Submission #825653

#TimeUsernameProblemLanguageResultExecution timeMemory
825653Shreyan_PaliwalValley (BOI19_valley)C++17
0 / 100
289 ms28068 KiB
// // #pragma GCC optimize("Ofast")
// // #include <bits/stdc++.h>
// // using namespace std;

// // #define int long long

// // const int maxn = 100000;
// // const int INF = 2000000000;

// // int n, s, q, e; // nodes, numshops, numqueries, valleynode
// // vector<pair<int,int>> adj[maxn];
// // pair<int,int> edges[maxn];
// // int shop[maxn]; // is shop?
// // int closest[maxn]; // closest shop in subtree

// // int dist[maxn]; // distance to root, set


// // int dpth[maxn]; // depth from root, set
// // int bl[maxn][20]; // set
// // int bld[maxn][20]; // array[nd] = - 2 * dist[nd] + min(dist[shop]) for shop in subtree[dist]


// // void dfs(int nd, int par, int pardist, int d) {
// //     // set depth
// //     dpth[nd] = d;

// //     // set binary lifting
// //     bl[nd][0] = par;
// //     for (int i = 1; i < 20; i++) bl[nd][i] = bl[bl[nd][i-1]][i-1];

// //     // recurse dfs, set distance from root
// //     for (auto i : adj[nd])
// //         if (i.first != par) {
// //             dist[i.first] = dist[nd] + i.second;    
// //             dfs(i.first, nd, i.second, d+1);
// //         }
    
// //     // init closest shop in subtree
// //     closest[nd] = shop[nd] ? 0 : INF;   
// //     for (auto i : adj[nd])
// //         if (i.first != par)
// //             closest[nd] = min(closest[nd], i.second + closest[i.first]);

// //     return;
// // }

// // void dfs_bld(int nd) {
// //     if (closest[nd] == INF) bld[nd][0] = INF;
// //     else bld[nd][0] = -dist[nd] + closest[nd];
// //     for (int i = 1; i < 20; i++) bld[nd][i] = min(bld[nd][i-1], bld[bl[nd][i-1]][i-1]);

// //     for (auto i : adj[nd])
// //         if (i.first != bl[nd][0])
// //             dfs_bld(i.first);
// // }

// // inline int jmp(int nd, int k) {
// //     for (int i = 19; i >= 0; i--) if ((k >> i) & 1) nd = bl[nd][i];
// //     return nd;
// // }

// // inline bool on_path(int nd, int nd2) {
// //     // checking if nd2 is on nd's path to root
// //     return (dpth[nd] >= dpth[nd2] && jmp(nd, dpth[nd] - dpth[nd2]) == nd2);
// // }

// // void solve() {
// //     cin >> n >> s >> q >> e; e--;
// //     for (int i = 0; i < n-1; i++) {
// //         int c; cin >> edges[i].first >> edges[i].second >> c;
// //         edges[i].first--, edges[i].second--;
// //         adj[edges[i].first].push_back({edges[i].second, c});
// //         adj[edges[i].second].push_back({edges[i].first, c});
// //     }

// //     for (int i = 0; i < s; i++) { int a; cin >> a; a--; shop[a] = 1; }

// //     dfs(e, e, 0, 0);
// //     dfs_bld(e);

// //     for (int i = 0; i < q; i++) {
// //         // a is a removed, b is b to find
// //         int a, b; cin >> a >> b; a--, b--;

// //         if (dpth[edges[a].first] < dpth[edges[a].second]) 
// //             swap(edges[a].first, edges[a].second);

// //         // check if escape possible
// //         if (!on_path(b, edges[a].first)) {
// //             cout << "escaped" << endl;
// //             continue;
// //         }

// //         // not possible, so search
// //         int val = INF;
// //         int B = b;
// //         for (int i = 19; i >= 0; i--) 
// //             if (((dpth[edges[a].first] - dpth[b] + 1) >> i) & 1)
// //                 val = min(val, bld[b][i]), 
// //                 b = bl[b][i];

// //         if (val == INF) {
// //             cout << "oo" << endl;
// //             continue;
// //         }

// //         cout << val + dist[B] << endl;
// //         continue;
// //     }

// // }

// // signed main() {
// //     cin.tie(nullptr) -> ios::sync_with_stdio(false);
// //     // freopen("main.in", "r", stdin);
// //     int t; 
// //     // cin >> t;
// //     t=1;
// //     while(t--) solve();
// //     return 0;
// // }

// #include <bits/stdc++.h>
// using namespace std;

// #define int long long

// const int maxn = 200000;
// const int INF = 1ll << 60;

// int n, s, q, e;

// vector<pair<int,int>> adj[maxn];
// pair<int,int> edges[maxn];

// int dist[maxn];
// int dpth[maxn];
// int closest[maxn];
// int shop[maxn];

// int bl[maxn][20];
// int bld[maxn][20];

// int st[maxn], en[maxn], cur = 0;

// void dfs(int nd, int par, int d) {
//     st[nd] = cur++;
//     dist[nd] = dist[par] + d;
//     dpth[nd] = dpth[par] + 1;

//     for (auto i : adj[nd])
//         if (i.first != par)
//             dfs(i.first, nd, i.second);

//     closest[nd] = (shop[nd] ? dist[nd] : INF);
//     for (auto i : adj[nd])
//         if (i.first != par && closest[i.first] != INF)
//             closest[nd] = min(closest[nd], closest[i.first]);
    
//     en[nd] = cur++;
// }

// void dfs_bl(int nd, int par) {
//     bl[nd][0] = par;
//     bld[nd][0] = (closest[nd] == INF ? INF : closest[nd] - 2 * dist[nd]);

//     for (int i = 1; i < 20; i++) bl[nd][i] = bl[bl[nd][i-1]][i-1];
//     for (int i = 1; i < 20; i++) bld[nd][i] = min(bld[nd][i-1], bld[bl[nd][i-1]][i-1]);

//     for (auto i : adj[nd])
//         if (i.first != par)
//             dfs_bl(i.first, nd);
// }

// signed main() {
//     // freopen("main.in", "r", stdin);

//     cin >> n >> s >> q >> e; e--;

//     for (int i = 0; i < n-1; i++) {
//         int a, b, c; cin >> a >> b >> c; a--, b--;
//         adj[a].push_back({b, c});
//         adj[b].push_back({a, c});
//         edges[i] = make_pair(b, c);
//     }

//     for (int i = 0; i < s; i++) {
//         int a; cin >> a; a--;
//         shop[a] = 1;
//     }

//     dfs(e, e, 0);
//     dfs_bl(e, e);

//     for (int i = 0; i < n-1; i++)
//         if (dpth[edges[i].first] < dpth[edges[i].second])
//             swap(edges[i].first, edges[i].second);

//     for (int i = 0; i < q; i++) {
//         int a, b; cin >> a >> b; a--, b--;
//         // if (dpth[edges[a].first] < dpth[edges[a].second]) swap(edges[a].first, edges[a].second);

//         // can escape?
//         if (!(st[edges[a].first] <= st[b] && en[b] <= en[edges[a].first])) {
//             cout << "escaped" << endl;
//             continue;
//         }

//         int cost = INF;
//         int nd = b;
//         for (int i = 19; i >= 0; i--)
//             if (((dpth[b] - dpth[edges[a].first]) >> i) & 1)
//                 cost = min(cost, bld[nd][i]), 
//                 nd = bl[nd][i];
//         cost = min(cost, bld[nd][0]);

//         if (cost == INF) { cout << "oo" << endl; continue; }

//         cout << cost + dist[b] << endl;
//         continue;
//     }

//     return 0;
// }


#include <bits/stdc++.h>

using namespace std;

const int maxn = 200005;
const int maxlg = 20;
const int inf = 1LL << 60;

vector<pair<int, int>> adj[maxn];
int height[maxn];
int lvl[maxn];
int dp[maxn];
bool store[maxn];
int st[maxn];
int en[maxn];
int cur;

void dfs(int nd, int par, int d) {
  st[nd] = ++cur;
  
  height[nd] = d;
  lvl[nd] = lvl[par] + 1;
  
    for (auto i : adj[nd])
        if (i.first != par)
            dfs(i.first, nd, d + i.second);

  if (store[nd]) {
    dp[nd] = height[nd];
  } else {
    dp[nd] = inf;
    for (pair<int, int> nxt : adj[nd]) {
      if (nxt.first != par) {
        dp[nd] = min(dp[nd], dp[nxt.first]);
      }
    }
  }

  en[nd] = cur;
}

bool is_parent (int u, int par) {
  return st[par] <= st[u] && en[u] <= en[par];
}

int jmp [maxn][maxlg];
int ans_jmp [maxn][maxlg];

void build_jmp (int nd, int par) {
  jmp[nd][0] = par;
  if (dp[nd] == inf) {
    ans_jmp[nd][0] = inf;
  } else {
    ans_jmp[nd][0] = dp[nd] - 2 * height[nd];
  }

  for (int i = 1; i < maxlg; i++) {
    jmp[nd][i] = jmp[jmp[nd][i - 1]][i - 1];
    ans_jmp[nd][i] = min(ans_jmp[nd][i - 1], ans_jmp[jmp[nd][i - 1]][i - 1]);
  }

  for (pair<int, int> nxt : adj[nd]) {
    if (nxt.first != par) {
      build_jmp(nxt.first, nd);
    }
  }
}

int query (int nd, int forb) {
  if (!is_parent(nd, forb)) {
    return -1;
  }

  int cur_h = height[nd];
  
  int diff = lvl[nd] - lvl[forb];
  int ans = inf;
  for (int i = maxlg - 1; i >= 0; i--) {
    if (diff & 1 << i) {
      ans = min(ans, ans_jmp[nd][i]);
      nd = jmp[nd][i];
    }
  }
  ans = min(ans, ans_jmp[nd][0]);

  if (ans != inf) {
    ans += cur_h;
  }
  
  return ans;
}

signed main () {
  int vertexc, storec, queryc, root;
  cin >> vertexc >> storec >> queryc >> root;

  vector<pair<int, int>> edges;
  for (int i = 0; i < vertexc - 1; i++) {
    int u, v, w;
    cin >> u >> v >> w;

    adj[u].push_back(make_pair(v, w));
    adj[v].push_back(make_pair(u, w));
    edges.push_back(make_pair(u, v));
  }

  for (int i = 0; i < storec; i++) {
    int x;
    cin >> x;
    store[x] = true;
  }

  dfs(root, root, 0);
  build_jmp(root, root);
  
  for (int i = 0; i < vertexc - 1; i++) {
    if (lvl[edges[i].first] < lvl[edges[i].second]) {
      swap(edges[i].first, edges[i].second);
    }
  }
  
  for (int i = 0; i < queryc; i++) {
    int forb_id, cur_vertex;
    cin >> forb_id >> cur_vertex;

    int ans = query(cur_vertex, edges[forb_id - 1].first);
    if (ans == -1) {
      cout << "escaped" << '\n';
    } else if (ans == inf) {
      cout << "oo" << '\n';
    } else {
      cout << ans << '\n';
    }
  }
}

Compilation message (stderr)

valley.cpp:234:21: warning: overflow in conversion from 'long long int' to 'int' changes value from '1152921504606846976' to '0' [-Woverflow]
  234 | const int inf = 1LL << 60;
      |                 ~~~~^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...