Submission #425179

# Submission time Handle Problem Language Result Execution time Memory
425179 2021-06-12T14:40:50 Z timmyfeng Simurgh (IOI17_simurgh) C++17
19 / 100
327 ms 6596 KB
#include <bits/stdc++.h>
using namespace std;

//#include "simurgh.h"

int count_common_roads(const vector<int> &s);

const int N = 500;

int par[N], edge[N], depth[N], deg[N], matches[N], dsu[N], n;
bool royal[N], visited[N], observed[N];
vector<int> span, ans, not_ans, u, v;
vector<array<int, 2>> adj[N];

void dfs(int u) {
    visited[u] = true;
    for (auto [c, e] : adj[u]) {
        if (!visited[c]) {
            span.push_back(e);
            depth[c] = depth[u] + 1;
            edge[c] = e;
            par[c] = u;
            dfs(c);
        }
    }
}

int find(int u) {
    return dsu[u] < 0 ? u : dsu[u] = find(dsu[u]);
}

bool unite(int u, int v) {
    u = find(u), v = find(v);
    if (u != v) {
        if (-dsu[u] > -dsu[v]) {
            swap(u, v);
        }
        dsu[v] += dsu[u];
        dsu[u] = v;
        return true;
    }
    return false;
}

int get(vector<int> &tree) {
    fill(dsu, dsu + n, -1);

    for (auto i : tree) {
        unite(u[i], v[i]);
    }

    for (auto i : not_ans) {
        if (unite(u[i], v[i])) {
            tree.push_back(i);
        }
    }

    int offset = 0;
    for (auto i : ans) {
        if (unite(u[i], v[i])) {
            tree.push_back(i);
            ++offset;
        }
    }

    return offset;
}

vector<int> find_roads(int n, vector<int> u, vector<int> v) {
    int m = u.size(); ::n = n, ::u = u, ::v = v;

    for (int i = 0; i < m; ++i) {
        adj[u[i]].push_back({v[i], i});
        adj[v[i]].push_back({u[i], i});
    }

    dfs(0);

    int init = count_common_roads(span);
    for (int i = 0; i < m; ++i) {
        if (depth[u[i]] > depth[v[i]]) {
            swap(u[i], v[i]);
        }

        if (depth[u[i]] + 1 == depth[v[i]]) {
            continue;
        }

        bool learn = false;
        for (int j = v[i]; j != u[i]; j = par[j]) {
            learn |= !observed[j];
        }

        if (!learn) {
            continue;
        }

        int reference = -1, mini = n - 1, maxi = 0;
        for (int j = v[i]; j != u[i]; j = par[j]) {
            vector<int> cycle = span;
            cycle.erase(find(cycle.begin(), cycle.end(), edge[j]));
            cycle.push_back(i);

            int value = -1;
            if (!observed[j]) {
                value = matches[j] = count_common_roads(cycle);
            } else if (reference == -1) {
                value = count_common_roads(cycle);
                reference = j;
            }

            if (value != -1) {
                mini = min(mini, value);
                maxi = max(maxi, value);
            }
        }

        for (int j = v[i]; j != u[i]; j = par[j]) {
            if (!observed[j]) {
                observed[j] = true;
                if (mini == maxi) {
                    if (reference == -1) {
                        royal[j] = mini < init;
                    } else {
                        royal[j] = royal[reference];
                    }
                } else {
                    royal[j] = matches[j] == mini;
                }
            }
        }
    }

    for (int i = 1; i < n; ++i) {
        (royal[i] ? ans : not_ans).push_back(edge[i]);
    }

    vector<int> stk;
    for (int i = 0; i < n; ++i) {
        vector<int> star;
        for (auto [j, e] : adj[i]) {
            if (count(ans.begin(), ans.end(), e) == 0) {
                star.push_back(e);
            }
        }
        int offset = get(star);

        deg[i] = count_common_roads(star) - offset;
        if (deg[i] == 1) {
            stk.push_back(i);
        }
    }

    while (!stk.empty()) {
        int i = stk.back();
        stk.pop_back();
        if (deg[i] == 0) {
            continue;
        }

        vector<int> candidates;
        for (auto [j, e] : adj[i]) {
            if (count(ans.begin(), ans.end(), e) == 0) {
                candidates.push_back(e);
            }
        }

        int low = 0, high = candidates.size() - 1;
        while (low < high) {
            int mid = (low + high) / 2;

            vector<int> star = vector<int>(candidates.begin(), candidates.begin() + mid + 1);
            int offset = get(star);

            if (count_common_roads(star) - offset > 0) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        int e = candidates[low], j = i ^ u[e] ^ v[e];
        ans.push_back(e);
        if (--deg[j] == 1) {
            stk.push_back(j);
        }
    }

    return ans;
}
# Verdict Execution time Memory Grader output
1 Correct 1 ms 204 KB correct
2 Correct 1 ms 204 KB correct
3 Correct 1 ms 204 KB correct
4 Correct 1 ms 204 KB correct
5 Correct 0 ms 204 KB correct
6 Correct 1 ms 204 KB correct
7 Correct 1 ms 204 KB correct
8 Correct 1 ms 204 KB correct
9 Incorrect 1 ms 308 KB WA in grader: NO
10 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 204 KB correct
2 Correct 1 ms 204 KB correct
3 Correct 1 ms 204 KB correct
4 Correct 1 ms 204 KB correct
5 Correct 0 ms 204 KB correct
6 Correct 1 ms 204 KB correct
7 Correct 1 ms 204 KB correct
8 Correct 1 ms 204 KB correct
9 Incorrect 1 ms 308 KB WA in grader: NO
10 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 204 KB correct
2 Correct 1 ms 204 KB correct
3 Correct 1 ms 204 KB correct
4 Correct 1 ms 204 KB correct
5 Correct 0 ms 204 KB correct
6 Correct 1 ms 204 KB correct
7 Correct 1 ms 204 KB correct
8 Correct 1 ms 204 KB correct
9 Incorrect 1 ms 308 KB WA in grader: NO
10 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 204 KB correct
2 Correct 1 ms 204 KB correct
3 Correct 188 ms 4640 KB correct
4 Correct 326 ms 6524 KB correct
5 Correct 323 ms 6476 KB correct
6 Correct 313 ms 6488 KB correct
7 Correct 311 ms 6520 KB correct
8 Correct 318 ms 6484 KB correct
9 Correct 323 ms 6596 KB correct
10 Correct 314 ms 6472 KB correct
11 Correct 321 ms 6520 KB correct
12 Correct 316 ms 6500 KB correct
13 Correct 1 ms 204 KB correct
14 Correct 327 ms 6516 KB correct
15 Correct 316 ms 6504 KB correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 204 KB correct
2 Correct 1 ms 204 KB correct
3 Correct 1 ms 204 KB correct
4 Correct 1 ms 204 KB correct
5 Correct 0 ms 204 KB correct
6 Correct 1 ms 204 KB correct
7 Correct 1 ms 204 KB correct
8 Correct 1 ms 204 KB correct
9 Incorrect 1 ms 308 KB WA in grader: NO
10 Halted 0 ms 0 KB -