Submission #1343076

#TimeUsernameProblemLanguageResultExecution timeMemory
1343076mehrzadWorld Map (IOI25_worldmap)C++17
72 / 100
62 ms8548 KiB

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

vector<vector<int>> create_map(int N, int M,
                               vector<int> A, vector<int> B) {
    
    // special case N==1
    if (N == 1) {
        return {{1}};
    }

    // build adjacency lists of the input graph
    vector<vector<int>> g(N + 1);
    for (int i = 0; i < M; ++i) {
        int u = A[i], v = B[i];
        g[u].push_back(v);
        g[v].push_back(u);
    }

    // ----- spanning tree (BFS from vertex 1) -----
    vector<vector<int>> tree_adj(N + 1);
    vector<bool> vis(N + 1, false);
    queue<int> q;
    q.push(1);
    vis[1] = true;
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v : g[u]) {
            if (!vis[v]) {
                vis[v] = true;
                tree_adj[u].push_back(v);
                tree_adj[v].push_back(u);
                q.push(v);
            }
        }
    }

    // mark tree edges
    vector<vector<bool>> in_tree(N + 1, vector<bool>(N + 1, false));
    for (int u = 1; u <= N; ++u) {
        for (int v : tree_adj[u]) {
            if (u < v) {
                in_tree[u][v] = in_tree[v][u] = true;
            }
        }
    }

    // ----- Euler tour of the tree -----
    vector<int> seq;
    function<void(int,int)> dfs_euler = [&](int u, int p) {
        seq.push_back(u);
        for (int v : tree_adj[u]) {
            if (v != p) {
                dfs_euler(v, u);
                seq.push_back(u);
            }
        }
    };
    dfs_euler(1, 0);                // root at 1

    // ----- classify edges -----
    vector<vector<int>> extra_from(N + 1);   // for source vertices
    vector<bool> is_source(N + 1, false);

    for (int i = 0; i < M; ++i) {
        int u = A[i], v = B[i];
        if (!in_tree[u][v]) {               // non‑tree edge
            int src = min(u, v);             // cover it from the smaller vertex
            int dst = max(u, v);
            extra_from[src].push_back(dst);
            is_source[src] = true;
        }
    }

    // ----- prepare rows (starting from the Euler tour) -----
    vector<int> rows = seq;

    // insert two extra rows for every source vertex, creating a block of three
    for (int u = 1; u <= N; ++u) {
        if (!is_source[u]) continue;

        // check if a block already exists
        bool has_block = false;
        for (size_t i = 0; i + 2 < rows.size(); ++i) {
            if (rows[i] == u && rows[i+1] == u && rows[i+2] == u) {
                has_block = true;
                break;
            }
        }
        if (has_block) continue;

        // otherwise create the block by inserting two copies of u
        size_t idx = 0;
        while (rows[idx] != u) ++idx;      // first occurrence
        rows.insert(rows.begin() + idx + 1, u);
        rows.insert(rows.begin() + idx + 2, u);
        // now rows[idx..idx+2] are u,u,u
    }

    int K = rows.size();
    vector<vector<int>> C(K, vector<int>(K));

    // initial fill: every cell in row i gets colour rows[i]
    for (int i = 0; i < K; ++i)
        for (int j = 0; j < K; ++j)
            C[i][j] = rows[i];

    // ----- locate the middle row of each block -----
    vector<int> mid_row(N + 1, -1);
    for (int u = 1; u <= N; ++u) {
        if (!is_source[u]) continue;
        for (size_t i = 0; i + 2 < rows.size(); ++i) {
            if (rows[i] == u && rows[i+1] == u && rows[i+2] == u) {
                mid_row[u] = i + 1;         // the middle of the three
                break;
            }
        }
        // must have been created
    }

    // ----- create the non‑tree edges by modifying the middle row -----
    for (int u = 1; u <= N; ++u) {
        if (!is_source[u]) continue;
        int mr = mid_row[u];
        int col = 0;                           // use even columns
        for (int v : extra_from[u]) {
            C[mr][col] = v;
            col += 2;
        }
    }

    return C;
}
#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...