Submission #1279032

#TimeUsernameProblemLanguageResultExecution timeMemory
1279032Bui_Quoc_CuongCat Exercise (JOI23_ho_t4)C++20
100 / 100
165 ms50012 KiB
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;

int n;
int a[N];
vector <int> ke[N];
int par[N];

namespace sub1 {
    int dp[5005];
    int dist[5005][5005];

    void DFS (int u) {
        for (int &v : ke[u]) if (v != par[u]) {
            par[v] = u;
            DFS(v);
        }
    }

    int find_max (int root, int border, int lim) {   
        vector <int> vis(n + 2, 0);
        vis[root] = vis[border] = true;
        queue <int> que;
        int max_node = 0;
        que.push(root);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            if (a[u] > a[max_node]) max_node = u;
            vis[u] = true;  
            for (int &v : ke[u]) if (!vis[v] && a[v] < lim) {
                que.push(v);
            }
        }
        return max_node;
    }

    int find_max_son (int u, int p, int lim) {
        int max_son = u;
        for (int &v : ke[u]) {
            if (v == p || a[v] > lim) continue;
            int choke = find_max_son (v, u, lim);
            if (a[choke] > a[max_son]) max_son = choke;
        }
        return max_son;
    }

    int dfs (int u, int p) {   
        if (dp[u] != - 1) return dp[u];
        dp[u] = 0;

        vector <int> umax;
        int s0 = find_max (u, p, a[u]);

        if (s0 != - 1 && s0 != u) umax.push_back(s0);

        for (int &v : ke[u]) if (a[v] < a[u]) {
            int sv = find_max_son (v, u, a[u]);
            if (sv != u) umax.push_back(sv);
        }

        for (int &v : umax) {
            dp[u] = max(dp[u], dfs(v, u) + dist[u][v]);
        }

        return dp[u];
    }   

    void solve () {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                dist[i][j] = 2e9;
            }
            queue <int> que;
            dist[i][i] = 0;
            que.push(i);
            while (!que.empty()) {
                int u = que.front();
                que.pop();
                for (int &v : ke[u]) if (dist[i][v] > dist[i][u] + 1) {
                    dist[i][v] = dist[i][u] + 1;
                    que.push(v);
                }
            }
        }
        int root = max_element(a + 1, a + 1 + n) - a;
        DFS(root);
        memset(dp, - 1, sizeof dp);
        cout << dfs(root, 0);
    }
}

namespace sub2 {
    long long dp[N];
    int lab[N], max_node[N], vis[N];
    int P[N][20], h[N];

    void dfs (int u) {
        for (int &v : ke[u]) if (v != P[u][0]) {
            P[v][0] = u;
            for (int j = 1; (1 << j) <= n; j++) {
                P[v][j] = P[P[v][j - 1]][j - 1];
            }
            h[v] = h[u] + 1;
            dfs(v);
        }
    }

    int LCA (int u, int v) {
        if (h[u] < h[v]) swap (u, v);
        int z = __lg(h[u]);
        for (int s = z; s >= 0; s--) if (h[u] - h[v] >= (1 << s)) u = P[u][s];
        if (u == v) return u;
        for (int s = z; s >= 0; s--) if (P[u][s] != P[v][s]) u = P[u][s], v = P[v][s];
        return P[u][0];
    }

    int dist (int u, int v) {return h[u] + h[v] - 2 * h[LCA(u, v)];}

    int find (int x) {
        return lab[x] < 0 ? x : lab[x] = find(lab[x]);
    }

    bool joint (int u, int v) {
        int x = find(u), y = find(v);
        if (x == y) return false;
        if (lab[x] > lab[y]) swap(x, y);
        lab[x]+= lab[y];
        lab[y] = x;
        if (a[max_node[x]] < a[max_node[y]]) max_node[x] = max_node[y];
        return true;
    }

    void solve () {
        for (int i = 1; i <= n; i++) {
            lab[i] = - 1;
            max_node[i] = i;
        }   
        vector <pair <int, int>> sorted;
        for (int i = 1; i <= n; i++) {
            sorted.push_back(make_pair(a[i], i));
        }
        sort(sorted.begin(), sorted.end());
        int root = max_element(a + 1, a + 1 + n) - a;
        dfs(1);
        for (auto x : sorted) {
            int u = x.second;
            for (int &v : ke[u]) if (vis[v]) {
                dp[u] = max(dp[u], dp[max_node[find(v)]] + dist(max_node[find(v)], u));
                joint(u, v);
            }
            vis[u] = 1;
        }
        cout << dp[root];
    }
}

void solve () {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i < n; i++) {
        int u, v; cin >> u >> v;
        ke[u].push_back(v); ke[v].push_back(u);
    }
    sub2 :: solve();
}

signed main () {
    ios_base::sync_with_stdio(0); cin.tie(0);
    #define kieuoanh "joi23hot4"

    if (fopen(kieuoanh".inp", "r")) {
        freopen(kieuoanh".inp", "r", stdin); freopen(kieuoanh".out", "w", stdout);
    }

    solve();

    return 0;
}

Compilation message (stderr)

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