Submission #1349859

#TimeUsernameProblemLanguageResultExecution timeMemory
1349859trimkusWorld Map (IOI25_worldmap)C++20
100 / 100
28 ms2872 KiB
#include "worldmap.h"
#include <bits/stdc++.h>
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
using namespace std;
using ll = long long;


std::vector<std::vector<int>> create_map(int N, int M, std::vector<int> A, std::vector<int> B) {
  vector<vector<int>> adj(N + 1);
  vector<vector<int>> c(N + 1, vector<int>(N + 1));
  vector<int> cnt(N + 1);
  for (int i = 0; i < M; ++i) {
    adj[A[i]].push_back(B[i]);
    adj[B[i]].push_back(A[i]);
    cnt[A[i]] += 1;
    cnt[B[i]] += 1;
    c[A[i]][B[i]] = c[B[i]][A[i]] = 1;
  }
  int r = -1;
  {
    int mx = *max_element(begin(cnt) +1 ,end(cnt));
    for (int i = 1; i <= N; ++i) {
      if (cnt[i] == mx) {
        r = i;
        break;
      }
    }
  }
  vector<vector<int>> now;
  auto dfs = [&](auto& dfs, int v) -> void {
    vector<int> left;
    for (auto& u : adj[v]) {
      if (c[v][u]) {
        left.push_back(u);
        c[v][u] = c[u][v] = 0;
      }
    }
    if (sz(left) == 0) return;
    vector<int> add;
    for (auto& u : left) {
      add.push_back(u);
    }
    add.push_back(v);
    now.emplace_back(add);
    for (auto& u : left) {
      dfs(dfs, u);
      if (now.back().back() != v) now.push_back({v, v});
    }
  };
  dfs(dfs, r);
  if (N == 1) return {{1}};
  while (sz(now) && sz(now.back()) == 2 && now.back()[0] == now.back()[1]) now.pop_back();
  int C = N * 2;
  if (*max_element(all(cnt)) == N - 1) {
    vector<vector<int>> nnow;
    for (int i = 0; i < sz(now); ++i) {
      if (sz(now[i]) == 2 && now[i][0] == now[i][1]) continue;
      nnow.push_back(now[i]);
    }
    now.swap(nnow);
    vector<vector<int>> X(C, vector<int>(C));
    assert((C-1)/2>=sz(now));
    for (int i = 0; i < C; ++i) {
      if (i % 2 == 1 || i / 2 >= sz(now)) {
        for (int j = 0; j < C; ++j) {
          X.at(i).at(j) = r;
        }
      } else {
        int ptr = 0;
        for (int j = 0; j < sz(now[i/2]); ++j){
          X.at(i).at(ptr) = now[i/2][j];
          ptr+=1;
          X.at(i).at(ptr) = now[i/2].back();
          ptr+=1;
        }
        for (int j = ptr; j < C; ++j) {
          X.at(i).at(j) = r;
        }
      }
    }
    return X;
  }
  vector<vector<int>> X(C, vector<int>(C));
  int si = C - 1, sj = C - 1;
  auto fill = [&](int i, int j, vector<int> v) -> void {
    while (j >= 0 && X.at(i).at(j) != 0) j -= 1;
    while (j >= 0 && min(C - j, i + 1) < sz(v) - 1) j -= 1;
    if (j < 0) {
      j = 0;
      while (X.at(i).at(j) != 0) i -= 1;
      while (min(C - j, i + 1) < sz(v) - 1) i -= 1;
    }
    si = i;
    sj = j;
    for (int it = 0; it + 1 < sz(v); ++it) {
      X.at(i).at(j) = v[it];
      i -= 1;
      j += 1;
    }
    while (i >= 0 && j < C) {
      X.at(i).at(j) = v[sz(v) - 1];
      i -= 1;
      j += 1;
    }
  };
  for (auto& v : now) {
    if (v[0] == v[sz(v) - 1]) {
      fill(si, sj, {v[sz(v) - 1]});
      continue;
    }
    fill(si, sj, {v[sz(v) - 1]});
    fill(si, sj, v);
    fill(si, sj, {v[sz(v) - 1]});
  }
  auto bfs = [&](int si, int sj) -> void {
    int Z = X.at(si).at(sj);
    queue<pair<int, int>> q;
    q.push({si, sj});
    vector<int> dx = {0, 1, 0, -1}, dy = {1, 0, -1, 0};
    while (sz(q)) {
      auto [i, j] = q.front();
      q.pop();
      for (int k = 0; k < 4; ++k) {
        int ni = i + dx[k];
        int nj = j + dy[k];
        if (ni < 0 || nj < 0 || ni >= sz(X) || nj >= sz(X)) continue;
        if (X[ni][nj] == 0) {
          q.push({ni, nj});
          X[ni][nj] = Z;
        }
      }
    }
  };
  if (X.at(0).at(0) != 0) bfs(0, 0);
  if (X.at(C - 1).at(C - 1) != 0) bfs(C - 1, C - 1);
  for (int i = 0; i < C; ++i) {
    for (int j = 0; j < C; ++j) {
      if (X.at(i).at(j) != 0) {
        bfs(i, j);
      }
    }
  }
  return X;
}
#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...