제출 #443332

#제출 시각아이디문제언어결과실행 시간메모리
443332mkisicSplit the Attractions (IOI19_split)C++14
40 / 100
102 ms16160 KiB
#include "split.h"
#include <queue>
#include <cassert>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

typedef pair <int, int> pii;

#define TRACE(x) cerr << #x << ' ' << x << endl
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define _ <<  " " << 

#define fi first
#define sec second

#define pb push_back

const int MAXN = 200100;

int n;

vector <int> v[MAXN];
vector <int> bio;

bool bfs(int start, vector <int> boje, vector <int> &ret) {
  queue <int> q;
  bio[start] = 1;
  int cnt = 0;
  q.push(start);
  vector <int> pos;
  while (!q.empty()) {
    int cvor = q.front();
    q.pop();
    cnt++;
    pos.pb(cvor);
    if (cnt == min(boje[2], boje[3])) {
      int boja = 3;
      if (boje[3] > boje[2]) boja = 2;
      for (auto &x : pos) ret[x] = boja;
      return true;
    }

    for (auto &ncvor : v[cvor]) {
      if (bio[ncvor]) continue;
      bio[ncvor] = 1;
      q.push(ncvor);
    }

  }
  return false;
}

vector <int> solve1(vector <int> boje) {
  vector <int> ret;
  ret.resize(n);

  REP(i, n) {
    if (bio[i]) continue;
    if (bfs(i, boje, ret)) {
      int boja = 2;
      if (boje[3] > boje[2]) boja = 3;
      REP(j, n) {
        if (ret[j] == 0 && boje[1]) {
          ret[j] = 1;
          boje[1]--;
        } else if (ret[j] == 0) ret[j] = boja;
      }
      return ret;
    }
  }

  return ret;
}

int sub[MAXN];

void dfs(int cvor, int par) {
  sub[cvor]++;
  for (auto &ncvor : v[cvor]) {
    if (ncvor == par) continue;
    dfs(ncvor, cvor);
    sub[cvor] += sub[ncvor];
  }
}

void bojaj(int cvor, int par, int boja, vector <int> &boje, vector <int> &ret) {
  if (boje[boja] == 0) return;
  ret[cvor] = boja;
  boje[boja]--;
  for (auto &ncvor : v[cvor]) {
    if (par == ncvor) continue;
    bojaj(ncvor, cvor, boja, boje, ret);
  }
}

vector <int> rezi(int A, int B, vector <int> boje, int ka, int kb) {
  vector <int> ret;
  ret.resize(n);
  bojaj(A, B, ka, boje, ret);
  bojaj(B, A, kb, boje, ret);
  REP(i, n) if (!ret[i]) ret[i] = 6 - ka - kb;
  return ret;
}

vector <int> stablo(vector <int> boje) {
  dfs(0, -1);
  vector <pii> B;
  FOR(i, 1, 4) B.pb({boje[i], i});
  sort(B.begin(), B.end());
  REP(i, MAXN) {
    for (auto &j : v[i]) {
      int x = i, y = j;
      if (sub[x] > sub[y]) swap(x, y);
      int ostalo = n - sub[x];
      if (ostalo >= B[0].fi && sub[x] >= B[1].fi) {
        return rezi(y, x, boje, B[0].sec, B[1].sec);
      }
      if (ostalo >= B[1].fi && sub[x] >= B[0].fi) {
        return rezi(x, y, boje, B[0].sec, B[1].sec);
      }
    }
  }
  vector <int> ret;
  ret.resize(n);
  return ret;
}

vector <int> tmp;

void f(int cvor, int par) {
  tmp.pb(cvor);
  bio[cvor] = 1;
  for (auto &ncvor : v[cvor]) {
    if (bio[ncvor]) continue;
    f(ncvor, cvor);
  }
}

bool cmp(const vector <int> &a, const vector <int> &b) {
  return a.size() < b.size();
}

vector <int> lanci(vector <int> boje) {
  vector <pii> B;
  FOR(i, 1, 4) B.pb({boje[i], i});
  sort(B.begin(), B.end());
  vector <vector <int> > l;
  REP(i, n) {
    if (!bio[i] && v[i].size() <= 1) {
      tmp.clear();
      f(i, -1);
      l.pb(tmp);
    }
  }
  REP(i, n) {
    if (!bio[i]) {
      tmp.clear();
      f(i, -1);
      l.pb(tmp);
    }
  }
  sort(l.begin(), l.end(), cmp);
  int tu = 0;
  vector <int> ret;
  ret.resize(n);
  for (auto &L : l) {
    if (L.size() >= B[0].fi + B[1].fi) {
      REP(i, B[0].fi) ret[L[i]] = B[0].sec;
      FOR(i, B[0].fi, B[0].fi + B[1].fi) ret[L[i]] = B[1].sec;
      REP(i, n) if (!ret[i]) ret[i] = B[2].sec;
      return ret;
    }
  }

  int ok = 0;
  REP(t, 2) {
    for (auto &L : l) {
      if (L.size() >= B[t].fi) {
        REP(i, B[t].fi) ret[L[i]] = B[t].sec;
        ok++;
        break;
      }
    }
  }

  if (ok == 2) REP(i, n) if (!ret[i]) ret[i] = B[2].sec;
  else {
    ret.clear();
    ret.resize(n);
  }
  return ret;
}

vector<int> find_split(int N, int a, int b, int c, vector<int> p, vector<int> q) {
  n = N;
  bio.resize(n);
  REP(i, p.size()) {
    v[p[i]].pb(q[i]);
    v[q[i]].pb(p[i]);
  }
  vector <int> boje = {0, a, b, c};

  int deg = 0;
  REP(i, n) deg = max(deg, (int)v[i].size());

  if (deg <= 2) return lanci(boje);
  if (p.size() == n - 1) return stablo(boje);
  return solve1(boje);
}

컴파일 시 표준 에러 (stderr) 메시지

split.cpp: In function 'std::vector<int> lanci(std::vector<int>)':
split.cpp:171:18: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  171 |     if (L.size() >= B[0].fi + B[1].fi) {
      |                  ^
split.cpp:182:20: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  182 |       if (L.size() >= B[t].fi) {
      |                    ^
split.cpp:190:6: warning: suggest explicit braces to avoid ambiguous 'else' [-Wdangling-else]
  190 |   if (ok == 2) REP(i, n) if (!ret[i]) ret[i] = B[2].sec;
      |      ^
split.cpp:167:7: warning: unused variable 'tu' [-Wunused-variable]
  167 |   int tu = 0;
      |       ^~
split.cpp: In function 'std::vector<int> find_split(int, int, int, int, std::vector<int>, std::vector<int>)':
split.cpp:13:42: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   13 | #define FOR(i, a, b) for (int i = (a); i < (b); i++)
      |                                          ^
split.cpp:14:19: note: in expansion of macro 'FOR'
   14 | #define REP(i, n) FOR(i, 0, n)
      |                   ^~~
split.cpp:201:3: note: in expansion of macro 'REP'
  201 |   REP(i, p.size()) {
      |   ^~~
split.cpp:211:16: warning: comparison of integer expressions of different signedness: 'std::vector<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  211 |   if (p.size() == n - 1) return stablo(boje);
      |       ~~~~~~~~~^~~~~~~~
#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...