Submission #292032

#TimeUsernameProblemLanguageResultExecution timeMemory
292032AlexLuchianovSplit the Attractions (IOI19_split)C++14
100 / 100
241 ms32744 KiB
#include "split.h"
#include <vector>
#include <cassert>
#include <cmath>
#include <algorithm>
#include <queue>
#include <iostream>

using ll = long long;
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))

std::vector<std::vector<int>> g;
std::vector<std::vector<int>> tree;

std::vector<int> level;
std::vector<int> sz;

void dfs(int node) {
  sz[node] = 1;
  for(int h = 0; h < g[node].size(); h++) {
    int to = g[node][h];
    if(level[to] == 0) {
      level[to] = level[node] + 1;
      dfs(to);
      tree[to].push_back(node);
      tree[node].push_back(to);

      sz[node] += sz[to];
    }
  }
}

int find_centroid(int node, int target) {
  for(int h = 0; h < tree[node].size(); h++) {
    int to = tree[node][h];
    if(sz[to] < sz[node] && target <= sz[to])
      return find_centroid(to, target);
  }
  return node;
}

void extract(int node, int parent, std::vector<int> &ord) {
  for(int h = 0; h < tree[node].size(); h++) {
    int to = tree[node][h];
    if(to != parent)
      extract(to, node, ord);
  } 
  ord.push_back(node);
}

void mark(int node, std::vector<int> &seen, std::vector<int> &sol, int &scount, int color) {
  if(scount == 0)
    return ;
  sol[node] = color;
  scount--;
  for(int h = 0; h < g[node].size(); h++) {
    int to = g[node][h];
    if(sol[to] == 3 && seen[to] == 1)
      mark(to, seen, sol, scount, color);
  }
}

std::vector<int> find_split(int n, int a, int b, int c, std::vector<int> p, std::vector<int> q) {
  g.resize(n);
  tree.resize(n);
  level.resize(n);
  sz.resize(n);

  int id1 = 1, id2 = 2, id3 = 3;
  if(b < a) {
    std::swap(id1, id2);
    std::swap(a, b);
  }
  if(c < a) {
    std::swap(id1, id3);
    std::swap(a, c);
  }
  if(c < b) {
    std::swap(id2, id3);
    std::swap(b, c);
  }

  for(int i = 0; i < p.size(); i++) {
    int x = p[i];
    int y = q[i];
    g[x].push_back(y);
    g[y].push_back(x);
  }
  level[0] = 1;
  dfs(0);
  std::vector<int> sol(n, 3);
  int centroid = find_centroid(0, sz[0] / 2);
  std::vector<int> mult(n);
  std::vector<std::vector<int>> big;

  for(int h = 0; h < tree[centroid].size(); h++) {
    std::vector<int> aux;
    extract(tree[centroid][h], centroid, aux);
    big.push_back(aux);
    for(int i = 0; i < aux.size(); i++)
      mult[aux[i]] = h;
  }

  std::vector<int> used(n);
  std::vector<std::vector<int>> bigg;
  bigg.resize(big.size());

  for(int i = 0; i < p.size(); i++) {
    if(p[i] == centroid || q[i] == centroid)
      continue;

    if(mult[p[i]] != mult[q[i]]) {
      bigg[mult[p[i]]].push_back(mult[q[i]]);
      bigg[mult[q[i]]].push_back(mult[p[i]]);
    }
  }

  for(int i = 0; i < big.size(); i++) {
    if(used[i] == 0) {
      std::vector<int> current;
      std::queue<int> q;
      q.push(i);
      used[i] = 1;
      while(0 < q.size() && current.size() < a) {
        int node = q.front();
        q.pop();
        for(int h = 0; h < big[node].size(); h++)
          current.push_back(big[node][h]);

        for(int h = 0; h < bigg[node].size(); h++) {
          int to = bigg[node][h];
          if(used[to] == 0) {
            used[to] = 1;
            q.push(to);
          }
        }
      }
      if(current.size() < a)
        continue;
      else {
        std::vector<int> seen(n, 0);
        for(int i = 0; i < current.size(); i++)
          seen[current[i]] = 1;
        mark(current[0], seen, sol, a, 1);
        seen = std::vector<int>(n, 1);
        mark(centroid, seen, sol, b, 2);
        for(int i = 0; i < sol.size(); i++)
          if(sol[i] == 1)
            sol[i] = id1;
          else if(sol[i] == 2)
            sol[i] = id2;
          else if(sol[i] == 3)
            sol[i] = id3;
        return sol;
      }
    }
  }
  return std::vector<int>(n, 0);
}

Compilation message (stderr)

split.cpp: In function 'void dfs(int)':
split.cpp:21:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   21 |   for(int h = 0; h < g[node].size(); h++) {
      |                  ~~^~~~~~~~~~~~~~~~
split.cpp: In function 'int find_centroid(int, int)':
split.cpp:35:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   35 |   for(int h = 0; h < tree[node].size(); h++) {
      |                  ~~^~~~~~~~~~~~~~~~~~~
split.cpp: In function 'void extract(int, int, std::vector<int>&)':
split.cpp:44:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   44 |   for(int h = 0; h < tree[node].size(); h++) {
      |                  ~~^~~~~~~~~~~~~~~~~~~
split.cpp: In function 'void mark(int, std::vector<int>&, std::vector<int>&, int&, int)':
split.cpp:57:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |   for(int h = 0; h < g[node].size(); h++) {
      |                  ~~^~~~~~~~~~~~~~~~
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:84:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   84 |   for(int i = 0; i < p.size(); i++) {
      |                  ~~^~~~~~~~~~
split.cpp:97:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   97 |   for(int h = 0; h < tree[centroid].size(); h++) {
      |                  ~~^~~~~~~~~~~~~~~~~~~~~~~
split.cpp:101:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  101 |     for(int i = 0; i < aux.size(); i++)
      |                    ~~^~~~~~~~~~~~
split.cpp:109:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  109 |   for(int i = 0; i < p.size(); i++) {
      |                  ~~^~~~~~~~~~
split.cpp:119:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  119 |   for(int i = 0; i < big.size(); i++) {
      |                  ~~^~~~~~~~~~~~
split.cpp:125:44: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  125 |       while(0 < q.size() && current.size() < a) {
      |                             ~~~~~~~~~~~~~~~^~~
split.cpp:128:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  128 |         for(int h = 0; h < big[node].size(); h++)
      |                        ~~^~~~~~~~~~~~~~~~~~
split.cpp:131:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  131 |         for(int h = 0; h < bigg[node].size(); h++) {
      |                        ~~^~~~~~~~~~~~~~~~~~~
split.cpp:139:25: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  139 |       if(current.size() < a)
      |          ~~~~~~~~~~~~~~~^~~
split.cpp:143:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  143 |         for(int i = 0; i < current.size(); i++)
      |                        ~~^~~~~~~~~~~~~~~~
split.cpp:148:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |         for(int i = 0; i < sol.size(); i++)
      |                        ~~^~~~~~~~~~~~
#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...