CSES - Leirikisa 2 - Results
Submission details
Task:Nautilus
Sender:MojoLake
Submission time:2023-04-18 17:01:18 +0300
Language:C++ (C++17)
Status:READY
Result:0
Feedback
groupverdictscore
#10
#20
#30
Test results
testverdicttimegroup
#10.01 s2, 3details
#20.01 s1, 2, 3details
#30.01 s1, 2, 3details
#40.01 s1, 2, 3details
#50.01 s1, 2, 3details
#60.01 s1, 2, 3details
#70.01 s1, 2, 3details
#80.01 s2, 3details
#90.01 s2, 3details
#100.01 s2, 3details
#110.01 s2, 3details
#120.01 s2, 3details
#130.01 s2, 3details
#140.01 s2, 3details
#150.01 s2, 3details
#160.01 s2, 3details
#170.01 s2, 3details
#180.01 s2, 3details
#190.01 s2, 3details
#200.01 s2, 3details
#210.01 s2, 3details
#220.01 s2, 3details
#230.01 s3details
#240.01 s3details
#250.01 s3details
#260.01 s3details
#270.01 s3details
#280.01 s3details
#290.01 s3details
#300.01 s3details
#310.01 s3details
#320.01 s3details
#330.01 s3details
#340.01 s3details
#350.01 s3details
#360.01 s3details
#370.01 s3details

Code

#include <bits/stdc++.h>

#define debug(x) cout << #x << ": " << x << "\n"
#define all(x) x.begin(), x.end()

using namespace std;
using std::sort;
using ll = long long;

const int N = 1e5 + 1;
const int LOG = 20;
const int M = 101;
const int inf = 1e9;
const ll LLinf = 1e16;

vector<pair<int, ll>> g[N];
vector<pair<int, int>> edges;
int par[N];
bool shop[N];
int jump[N][LOG], depth[N];
ll weight_d[N];


ll up[N];
vector<pair<ll, int>> down[N];


int n, s, q, e;


void first_dfs(int cur, int pre){
    par[cur] = pre;
    jump[cur][0] = pre;
    depth[cur] = depth[pre] + 1;

    for(auto [nex, w] : g[cur]){
        if(nex == pre)continue;
        // cost_jump[nex][0] = w;
        weight_d[nex] = weight_d[cur] + w;
        first_dfs(nex, cur);
    }
}


void create_jump(){

    for(int j = 1; j < LOG; ++j){
        for(int i = 1; i <= n; ++i){
            jump[i][j] = jump[jump[i][j-1]][j-1];
            // cost_jump[i][j] = cost_jump[i][j-1] + cost_jump[jump[i][j-1]][j-1];
        }
    }
}


bool solve(int ind, int node){

    auto [p, c] = edges[ind];
    if(par[c] != p)swap(p, c);
    assert(par[c] == p);
    // cout << p << " " << c << "\n";
    // cout << node << "\n";

    if(c == node)return 0;
    if(depth[c] >= depth[node])return 1;
    
    for(int j = LOG - 1; j >= 0; --j){
        int nex = jump[node][j];
        if(depth[nex] >= depth[c]){
            node = nex;
        }
    }
    // cqout << node << " " << c << "\n\n";

    return node != c;
}


ll calc_down(int cur, int pre){

    if(shop[cur])down[cur].push_back({0, -1});
    else down[cur].push_back({LLinf, -1});


    for(int i = 0; i < (int)g[cur].size(); ++i){
        auto [nex, w] = g[cur][i];
        if(nex == pre)continue;

        down[cur].push_back({calc_down(nex, cur) + w, nex});
    }  
    sort(all(down[cur]));
    return down[cur].begin()->first;
}

void calc_up(int cur, int pre, ll mn_dis){

    if(!shop[cur])up[cur] = mn_dis;

    for(int i = 0; i < (int)g[cur].size(); ++i){
        auto [nex, w] = g[cur][i];
        if(nex == pre)continue;

        ll add = down[cur].begin()->first ;
        if(down[cur].begin()->second == nex)add = down[cur][1].first;

        ll cur_mn = min(mn_dis, add) + w;

        calc_up(nex, cur, cur_mn);
    }
}

int lca(int a, int b){

    if(depth[a] < depth[b])swap(a, b);

    for(int j = LOG - 1; j >= 0; --j){
        int nex = jump[a][j];
        if(depth[nex] >= depth[b]){
            a = nex;
        }
    }

    assert(depth[a] == depth[b]);

    for(int j = LOG - 1; j >= 0; --j){
        while(jump[a][j] != jump[b][j]){
            a = jump[a][j];
            b = jump[b][j];
        }
    }
    if(a == b)return a;
    return jump[a][0];
}


ll dist(int a, int b){

    int c = lca(a, b);

    return weight_d[a] + weight_d[b] - 2ll * weight_d[c];
}


ll calc_min_dis(int ind, int node){

    auto [p, c] = edges[ind];
    if(par[c] != p)swap(p, c);
    assert(par[c] == p);
    
    ll dis = -1;

    assert(lca(node, c) == c);
    // cout << node << " " << p << " " << c << "\n";
    // cout << down[node].begin()->first << "\n";
    // cout << dist(node, c ) << "\n";
    if(node == c){
        dis = down[node].begin()->first;
    }else if(lca(node, c) == c){

        dis = down[node].begin()->first;

        if(up[node] <= up[c])dis = min(dis, up[node]);

        int node_up = node;
        for(int j = LOG - 1; j >= 0; --j){
            int nex = jump[node_up][j];
            if(depth[nex] > depth[c]){
                node_up = nex;
            }
        }

        // cout << node << " " << node_up << " " << p << " " << c << "\n";

        ll dis_down = down[c].begin()->first;
        if(down[c].begin()->second == node_up){
            dis_down = down[c][1].first;
        }
        dis = min(dis, dist(node, c) + dis_down);

        // cout << dist(node, c) << " " << dis_down << "\n";

        // ll x = dist(node, c) - dis_down;
        // if(x > 0)dis = min(dis, x);
        // cout << "yayy\n" << node << " " << c << "\n";
    }else if(lca(node, p) == p){
        ll dis_down = down[p].begin()->first;
        if(down[p].begin()->second == c){
            dis_down = down[p][1].first;
        }

        dis = min(down[node].begin()->first, dist(node, p) + min(up[p], dis_down));
        assert(0);
    }

    if(dis > (ll)1e15)return -1;
    return dis;
}


int main(){

    // cin.tie(0)->sync_with_stdio(0);
    cin >> n >> s >> q >> e;
    for(int _ = 0; _ < n - 1; ++_){
        int a, b; ll w; 
        cin >> a >> b >> w;
        g[a].push_back({b, w});
        g[b].push_back({a, w});
        edges.push_back({min(a, b), max(a, b)});
    }
    for(int _ = 0; _ < s; ++_){
        int c; cin >> c;
        shop[c] = 1;
    }

    first_dfs(e, 0);
    create_jump();
    calc_down(e, 0);
    calc_up(e, 0, shop[e] ? 0 : LLinf);

    // for(int i = 1; i <= n; ++i){
    //     cout << i << " " << up[i] << " " << down[i].begin()->first << "\n";
    // }

    while(q--){
        int I, R;
        cin >> I >> R;
        if(solve(I-1, R)){
            cout << "escaped\n";
        }else{
            ll res = calc_min_dis(I-1, R);
            if(res == -1)cout << "oo\n";
            else cout << res << "\n";
        }
    }



    // how to check if we can reach the root?
    // The road is cuts our way iff the endpoint
    // (p, c) has depth smaller AND lca(node, c) == p with
    // (note the special case, then we have to check)

    // How to find closest shop? First we can precompute
    // with tree dp to each direction for each node.
    // But how to handle the removal of an edge?
    // 
    // Let the edge removed be (p, c), that is, (parent, child)
    // and the node be a.
    // 
    // if c is an ancestor of a (lca(a, c) == c):
    //      answer is min(down[a], dis(a, c) + down[c])
    // else if p is an ancestor of a (lca(a, p) == p):
    //      answer is min(down[a], dis(a, p) + min(up[p], down[p] (not including the direction to c)))
    // else if p is in the subtree of a:
    //      answer is min(up[a], down[a] (not including direction of p), dis(a, p) - up[p] (if positive), dis(a, p) + down[p] (not including the direction of c))
    // else they just have a lowest common ancestor lca(a, p)
    //      answer is min(down[a], dis(a, lca) + up[lca], dis(a, lca) + down[lca] (not including the direction of p), dis(a, lca) + dis(lca, p) - up[p] (if this is positive))
    // think about the case when a is either p or a!!
    

}

Test details

Test 1

Group: 2, 3

Verdict:

input
5 9 7
...##....
..#.##..#
..#....##
.##...#..
...

correct output
22

user output
(empty)

Test 2

Group: 1, 2, 3

Verdict:

input
100 100 100
.................................

correct output
8272

user output
(empty)

Test 3

Group: 1, 2, 3

Verdict:

input
100 100 100
.#...#.#..#.....#.........#......

correct output
5

user output
(empty)

Test 4

Group: 1, 2, 3

Verdict:

input
100 100 100
.#...##...#...##....##.#.##..#...

correct output
1

user output
(empty)

Test 5

Group: 1, 2, 3

Verdict:

input
100 100 100
..#.#.#..###.#.#.##..########....

correct output
1

user output
(empty)

Test 6

Group: 1, 2, 3

Verdict:

input
100 100 100
.#.#.###########..#.###.######...

correct output
1

user output
(empty)

Test 7

Group: 1, 2, 3

Verdict:

input
100 100 100
##############################...

correct output
1

user output
(empty)

Test 8

Group: 2, 3

Verdict:

input
100 100 100
.................................

correct output
9503

user output
(empty)

Test 9

Group: 2, 3

Verdict:

input
100 100 100
#..#.##..#....##...#.##.##..#....

correct output
495

user output
(empty)

Test 10

Group: 2, 3

Verdict:

input
100 100 100
#.#...######.#####.#.##...#.##...

correct output
51

user output
(empty)

Test 11

Group: 2, 3

Verdict:

input
100 100 100
.#.#.###########..#.###.######...

correct output
34

user output
(empty)

Test 12

Group: 2, 3

Verdict:

input
100 100 100
##############################...

correct output
19

user output
(empty)

Test 13

Group: 2, 3

Verdict:

input
100 100 100
.................................

correct output
9801

user output
(empty)

Test 14

Group: 2, 3

Verdict:

input
100 100 100
..............#..................

correct output
7479

user output
(empty)

Test 15

Group: 2, 3

Verdict:

input
100 100 100
#.#.........###.#..#.#..####.#...

correct output
5328

user output
(empty)

Test 16

Group: 2, 3

Verdict:

input
100 100 100
.#.#.###########..#.###.######...

correct output
127

user output
(empty)

Test 17

Group: 2, 3

Verdict:

input
100 100 100
##############################...

correct output
19

user output
(empty)

Test 18

Group: 2, 3

Verdict:

input
100 100 100
.................................

correct output
10000

user output
(empty)

Test 19

Group: 2, 3

Verdict:

input
100 100 100
..............#..................

correct output
8047

user output
(empty)

Test 20

Group: 2, 3

Verdict:

input
100 100 100
#.#...######.#####.#.##...#.##...

correct output
3500

user output
(empty)

Test 21

Group: 2, 3

Verdict:

input
100 100 100
.#.#.###########..#.###.######...

correct output
1228

user output
(empty)

Test 22

Group: 2, 3

Verdict:

input
100 100 100
##############################...

correct output
43

user output
(empty)

Test 23

Group: 3

Verdict:

input
500 500 5000
.................................

correct output
249493

user output
(empty)

Test 24

Group: 3

Verdict:

input
500 500 5000
#..#.##..#....##...#.##.##..#....

correct output
222

user output
(empty)

Test 25

Group: 3

Verdict:

input
500 500 5000
.#####....####..###...####.#.#...

correct output
1268

user output
(empty)

Test 26

Group: 3

Verdict:

input
500 500 5000
#.#####.##..#####.####..######...

correct output
805

user output
(empty)

Test 27

Group: 3

Verdict:

input
500 500 5000
##############################...

correct output
349

user output
(empty)

Test 28

Group: 3

Verdict:

input
500 500 5000
.................................

correct output
249999

user output
(empty)

Test 29

Group: 3

Verdict:

input
500 500 5000
..............#..................

correct output
197917

user output
(empty)

Test 30

Group: 3

Verdict:

input
500 500 5000
#.#.........###.#..#.#..####.#...

correct output
79550

user output
(empty)

Test 31

Group: 3

Verdict:

input
500 500 5000
#.#####.##..#####.####..######...

correct output
1221

user output
(empty)

Test 32

Group: 3

Verdict:

input
500 500 5000
##############################...

correct output
1414

user output
(empty)

Test 33

Group: 3

Verdict:

input
500 500 5000
.................................

correct output
250000

user output
(empty)

Test 34

Group: 3

Verdict:

input
500 500 5000
..............#..................

correct output
199752

user output
(empty)

Test 35

Group: 3

Verdict:

input
500 500 5000
.#####....####..###...####.#.#...

correct output
87691

user output
(empty)

Test 36

Group: 3

Verdict:

input
500 500 5000
#.#####.##..#####.####..######...

correct output
30998

user output
(empty)

Test 37

Group: 3

Verdict:

input
500 500 5000
##############################...

correct output
1440

user output
(empty)