제출 #1273138

#제출 시각아이디문제언어결과실행 시간메모리
1273138strange420세계 지도 (IOI25_worldmap)C++20
36 / 100
42 ms4564 KiB
#include "worldmap.h"
#include <algorithm>
#include <iostream>
#include <functional>
#include <utility>
#include <cmath>
#include <cassert>

std::vector<int> spanning_tree(std::vector<std::vector<int>>& adj_list, std::vector<std::vector<int>>& adj_matrix) {
  std::function<bool(int, int)> dfs;
  std::vector<int> visited(adj_list.size(), 0), path;
  dfs = [&](int u, int p) {
    if (visited[u]) return false;
    visited[u] = 1;
    path.push_back(u);
    for (int v: adj_list[u])
      if (dfs(v, u)) path.push_back(u);
    return true;
  }; dfs(1, 0);

  for (int i=1; i<path.size(); i++) 
    adj_matrix[path[i-1]][path[i]] = adj_matrix[path[i]][path[i-1]] = 0;
  
  std::vector<std::vector<int>> new_adj_list(adj_list.size());
  for (int i=1; i<adj_matrix.size(); i++)
    for (int j=1; j<adj_matrix.size(); j++)
      if (adj_matrix[i][j])
        new_adj_list[i].push_back(j);
  adj_list = new_adj_list;
  return path;
}

std::vector<std::vector<int>> create_map(int N, int M, std::vector<int> A, std::vector<int> B) {
  // if (M == 0) {
  //   for (int i=1; i<=N; i++) {
  //     for (int j=i+1; j<=N; j++) {
  //       A.push_back(i);
  //       B.push_back(j);
  //     }
  //   }
  //   M = A.size();
  // }
  std::vector<std::vector<int>> adj_list(N+1);
  std::vector<std::vector<int>> adj_matrix(adj_list.size(), std::vector<int>(adj_list.size(), 0));
  for (int i=0; i<M; i++) {
    adj_list[A[i]].push_back(B[i]);
    adj_list[B[i]].push_back(A[i]);
    adj_matrix[A[i]][B[i]] = adj_matrix[B[i]][A[i]] = 1;
  }
  std::vector<int> partial = spanning_tree(adj_list, adj_matrix);

  // Diagonalization - Insert a new edge and take advantage of that edge
  int K = 3*N;
  std::vector<std::vector<int>> ans(K, std::vector<int>(K, 0));
  for (int i=0; i<K; i++) ans[0][i] = partial[i%partial.size()];

  int last_copy = 0;
  for (int i=1; i<K; i++) {
    // Merge node
    int index = -1;
    // for (int j=1; j<K-1 && index == -1; j++) {
    //   if (ans[i-1][j-1] == ans[i-1][j+1]) {
    //     ans[i][j] = ans[i-1][j-1];
    //     index = j;
    //   }
    // }

    for (int j=0; j<K && index == -1; j++) {
      for (int x=N; x>=1; x--) {
        if (adj_matrix[ans[i-1][j]][x]) {
          ans[i][j] = x;
          index = j;
          adj_matrix[ans[i-1][j]][x] = 0;
          adj_matrix[x][ans[i-1][j]] = 0;
          break;
        }
      }
    }
    
    if (index == -1) {
      for (int j=0; j<K; j++) {
        ans[i][j] = ans[last_copy][j];
      }
      last_copy = std::max(last_copy, 0);
      continue;
    }

    last_copy = i;
    for (int j=index+1; j<K; j++) {
      for (int x=N; x>=1; x--) {
        if (adj_matrix[ans[i-1][j]][x] && adj_matrix[x][ans[i][j-1]]) {
          ans[i][j] = x;
          adj_matrix[ans[i-1][j]][x] = 0;
          adj_matrix[x][ans[i-1][j]] = 0;
          adj_matrix[ans[i][j-1]][x] = 0;
          adj_matrix[x][ans[i][j-1]] = 0;
          break;
        }
      }

      if (ans[i][j] == 0) {
        // ans[i][j] = ans[i-1][std::min(j+1, K-1)];
        ans[i][j] = ans[i-1][j-1];
      }
    }

    for (int j=index-1; j>=0; j--) {
      for (int x=1; x<=N; x++) {
        if (adj_matrix[ans[i-1][j]][x] && adj_matrix[x][ans[i][j+1]]) {
          ans[i][j] = x;
          adj_matrix[ans[i-1][j]][x] = 0;
          adj_matrix[x][ans[i-1][j]] = 0;
          adj_matrix[ans[i][j+1]][x] = 0;
          adj_matrix[x][ans[i][j+1]] = 0;
          break;
        }
      }

      if (ans[i][j] == 0) {
        // ans[i][j] = ans[i-1][std::max(j-1, 0)];
        ans[i][j] = ans[i-1][j+1];
      }
    }
  }

  // // Write a checker to debug.
  // std::cout << "Final size: " << N << '\t' << M << '\n';
  // for (int i=0; i<ans.size(); i++) {
  //   for (int j=0; j<ans.size(); j++) {
  //     std::cout << ans[i][j] << ' ';
  //   }
  //   std::cout << '\n';
  // }
  // int validate[N+5][N+5];
  // memset(validate, 0, sizeof(validate));
  // for (int i=0; i<K; i++) {
  //   for (int j=0; j<K; j++) {
  //     if (i-1 >= 0) {
  //       if (std::min(ans[i][j], ans[i-1][j]) == 3
  //        && std::max(ans[i][j], ans[i-1][j]) == 7) {
  //         std::cout << i << '\t' << j << '\n';
  //       }
  //       validate[ans[i][j]][ans[i-1][j]] = 1;
  //       validate[ans[i-1][j]][ans[i][j]] = 1;
  //     }

  //     if (j-1 >= 0) {
  //       if (std::min(ans[i][j], ans[i][j-1]) == 3
  //        && std::max(ans[i][j], ans[i][j-1]) == 7) {
  //         std::cout << i << '\t' << j << '\n';
  //       }
  //       validate[ans[i][j]][ans[i][j-1]] = 1;
  //       validate[ans[i][j-1]][ans[i][j]] = 1;
  //     }
  //   }
  // }
  // for (int i=0; i<M; i++) {
  //   validate[A[i]][B[i]]--;
  //   validate[B[i]][A[i]]--;
  // }
  // bool flag = false;
  // for (int i=1; i<=N; i++)
  //   for (int j=i+1; j<=N; j++)
  //     if (validate[i][j] != 0) {
  //       std::cout << i << '\t' << j << '\t' << validate[i][j] << '\n';
  //       flag = true;
  //     }
  // if (flag) exit(-1);
  return ans;
}
#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...