답안 #781770

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
781770 2023-07-13T10:44:50 Z elazarkoren Valley (BOI19_valley) C++17
36 / 100
3000 ms 25884 KB
#include <bits/stdc++.h>
#define x first
#define y second
#define all(v) v.begin(), v.end()
#define chkmin(a, b) a = min(a, b)
#define chkmax(a, b) a = max(a, b)
// #define int ll
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll, ll> pii;
typedef vector<pii> vii;
 
const int MAX_N = 1e5 + 5;
const ll infinity = 1e18;
const int block = 300;
const int BITS = 17;
 
vector<tuple<int, ll, int>> tree[MAX_N];
bool shop[MAX_N];   
int a[MAX_N], b[MAX_N];
ll we[MAX_N];
int dp[BITS][MAX_N];
ll depth1[MAX_N], depth2[MAX_N];
 
void DfsDepth(int node, int parent, ll d1, int d2) {
    dp[0][node] = parent;
    depth1[node] = d1, depth2[node] = d2;
    for (auto [neighbor, w, i] : tree[node]) {
        if (neighbor != parent) DfsDepth(neighbor, node, d1 + w, d2 + 1);
    }
}
 
int Lca(int a, int b) {
    if (depth2[a] < depth2[b]) swap(a, b);
    for (int i = BITS - 1; i >= 0; i--) {
        if (((depth2[a] - depth2[b]) >> i) & 1) a = dp[i][a];
    }
    if (a == b) return a;
    for (int i = BITS - 1; i >= 0; i--) {
        if (dp[i][a] != dp[i][b]) {
            a = dp[i][a], b = dp[i][b];
        }
    }
    return dp[0][a];
}
 
ll Dist(int a, int b) {
    return depth1[a] + depth1[b] - 2 * depth1[Lca(a, b)];
}
 
bool Escaped(int r, int e, int i) {
    ll d1 = Dist(r, e);
    ll d2 = min(Dist(r, a[i]) + Dist(e, b[i]), Dist(r, b[i]) + Dist(e, a[i])) + we[i];
    return d1 != d2;
}
 
int que_i[MAX_N], que_r[MAX_N];
ll closest[MAX_N];
bitset<MAX_N> visited_edges;
int close_node[block + 1][block + 1];
int component[MAX_N];
 
ll ClosestDown(int node, int comp, int parent = -1) {
    component[node] = comp;
    for (auto [neighbor, w, i] : tree[node]) {
        if (visited_edges[i] || neighbor == parent) continue;
        ll c = ClosestDown(neighbor, comp, node);
        chkmin(closest[node], c + w);
    }
    if (shop[node]) closest[node] = 0;
    return closest[node];
}
 
void ClosestUp(int node, ll c = infinity, int parent = -1) {
    chkmin(closest[node], c);
    chkmin(c, closest[node]);
    for (auto [neighbor, w, i] : tree[node]) {
        if (visited_edges[i] || neighbor == parent) continue;
        ClosestUp(neighbor, c + w, node);
    }
}
 
int last_vis[block + 1];
int comps;
 
void ClosestNode(int node, int parent = 0) {
    if (parent && component[node] != component[parent]) {
        for (int i = 0; i < comps; i++) {
            if (last_vis[i] != -1) {
                close_node[component[node]][i] = last_vis[i];
                close_node[i][component[node]] = node;
            }
        }
    }
    for (auto [neighbor, w, i] : tree[node]) {
        last_vis[component[node]] = node;
        if (neighbor != parent) ClosestNode(neighbor, node);
    }
    last_vis[component[node]] = node;
}
 
int n, s, q, e;
ll ans[MAX_N];

void Dfs(int node, int parent, ll d, int bad, vii &v) {
    v.push_back({node, d});
    for (auto [neighbor, w, i] : tree[node]) {
        if (node == a[bad] && neighbor == b[bad] || node == b[bad] && neighbor == a[bad]) continue;
        if (neighbor != parent) Dfs(neighbor, node, d + w, bad, v);
    }
}

void Solve(int le, int ri) {
    visited_edges.reset();
    for (int t = le; t < ri; t++) {
        visited_edges[que_i[t]] = 1;
    }
    fill(closest, closest + n + 1, infinity);
    fill(component, component + n + 1, 0);
    comps = 0;
    for (int i = 1; i <= n; i++) {
        if (!component[i]) {
            ClosestDown(i, ++comps);
            ClosestUp(i);
        }
    }
    for (int i = 1; i <= n; i++) component[i]--;
    fill(last_vis, last_vis + comps, -1);
    ClosestNode(1);
    for (int t = le; t < ri; t++) {
        int i = que_i[t], r = que_r[t];
        if (Escaped(r, e, i)) {
            ans[t] = -1;
            continue;
        }
        if (s == n) {
            ans[t] = 0;
            continue;
        }
        int c = component[r];
        ans[t] = closest[r];
        for (int j = 0; j < comps; j++) {
            if (j == c) continue;
            int node = close_node[c][j];
            if (Escaped(r, node, i)) {
                chkmin(ans[t], Dist(r, node) + closest[node]);
            }
        }
    }
}
 
int32_t main() {
    ios_base::sync_with_stdio(false);
    cin >> n >> s >> q >> e;
    for (int i = 0; i < n - 1; i++) {
        a[i] = i + 1, b[i] = i + 2, we[i] = rand();
        cin >> a[i] >> b[i] >> we[i];
        tree[a[i]].push_back({b[i], we[i], i});
        tree[b[i]].push_back({a[i], we[i], i});
    }
    for (int i = 0; i < s; i++) {
        int x = rand() % n + 1;
        cin >> x;
        shop[x] = 1;
    }
    for (int t = 0; t < q; t++) {
        que_i[t] = rand() % (n - 1) + 1, que_r[t] = rand() % n + 1;
        cin >> que_i[t] >> que_r[t];
        que_i[t]--;
    }
    DfsDepth(1, 0, 0, 0);
    for (int i = 1; i < BITS; i++) {
        for (int j = 1; j <= n; j++) {
            dp[i][j] = dp[i - 1][dp[i - 1][j]];
        }
    }
    for (int le = 0; le < q; le += block) {
        Solve(le, min(le + block, q));
    }
    for (int i = 0; i < q; i++) {
        cout << (ans[i] == -1 ? "escaped" : (ans[i] == infinity ? "oo" : to_string(ans[i]))) << '\n';
    }
}

Compilation message

valley.cpp: In function 'void Dfs(int, int, ll, int, vii&)':
valley.cpp:110:28: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  110 |         if (node == a[bad] && neighbor == b[bad] || node == b[bad] && neighbor == a[bad]) continue;
      |             ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 93 ms 3104 KB Output is correct
2 Correct 70 ms 3128 KB Output is correct
3 Correct 71 ms 3168 KB Output is correct
4 Correct 7 ms 3236 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 93 ms 3104 KB Output is correct
2 Correct 70 ms 3128 KB Output is correct
3 Correct 71 ms 3168 KB Output is correct
4 Correct 7 ms 3236 KB Output is correct
5 Correct 18 ms 3356 KB Output is correct
6 Correct 28 ms 3284 KB Output is correct
7 Correct 7 ms 3264 KB Output is correct
8 Correct 20 ms 3284 KB Output is correct
9 Correct 28 ms 3332 KB Output is correct
10 Correct 8 ms 3156 KB Output is correct
11 Correct 3 ms 3284 KB Output is correct
12 Correct 3 ms 3328 KB Output is correct
13 Correct 3 ms 3284 KB Output is correct
14 Correct 23 ms 3348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 3057 ms 25884 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 93 ms 3104 KB Output is correct
2 Correct 70 ms 3128 KB Output is correct
3 Correct 71 ms 3168 KB Output is correct
4 Correct 7 ms 3236 KB Output is correct
5 Correct 18 ms 3356 KB Output is correct
6 Correct 28 ms 3284 KB Output is correct
7 Correct 7 ms 3264 KB Output is correct
8 Correct 20 ms 3284 KB Output is correct
9 Correct 28 ms 3332 KB Output is correct
10 Correct 8 ms 3156 KB Output is correct
11 Correct 3 ms 3284 KB Output is correct
12 Correct 3 ms 3328 KB Output is correct
13 Correct 3 ms 3284 KB Output is correct
14 Correct 23 ms 3348 KB Output is correct
15 Execution timed out 3057 ms 25884 KB Time limit exceeded
16 Halted 0 ms 0 KB -