제출 #438072

#제출 시각아이디문제언어결과실행 시간메모리
438072CyanForces열쇠 (IOI21_keys)C++17
100 / 100
1885 ms269212 KiB
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define debug(...) //ignore
typedef long long ll;
typedef pair<int, int> pii;
typedef long double ld;
typedef vector<int> vi;


std::vector<int> find_reachable(std::vector<int> r, std::vector<int> u, std::vector<int> v, std::vector<int> c) {
  int n = sz(r);

  debug(debugging::PRINT_STRUCT_NAME = false);


  struct info {
    unordered_map<int,vi> locked_edges; // edges per color
    vi unlocked_edges;
    unordered_set<int> colors;
    vi nodes;
    int leader = -1;
  };

  vi where(n);
  vector<info> comp(n);
  rep(i,0,n) comp[i].leader = where[i] = i;

  auto append = [&](vi&v, vi&q) {
    if(sz(v) < sz(q)) swap(v,q);
    for(int x : q) v.emplace_back(x);
    q.clear();
  };

  auto unlock = [&](info &a, int col) {
    if(a.colors.count(col)) return;
    a.colors.emplace(col);
    append(a.unlocked_edges, a.locked_edges[col]);
    a.locked_edges.erase(col);
  };

  auto join = [&](int i, int j) {
    if(sz(comp[i].nodes) < sz(comp[j].nodes)) swap(i, j);
    info &a = comp[i];
    info &b = comp[j];
    //assert(!a.bad && !b.bad);

    //assert(a.leader == i);

    for(int x : b.nodes) where[x] = a.leader;
    append(a.nodes, b.nodes);
    append(a.unlocked_edges, b.unlocked_edges);
    for(auto [col, v] : b.locked_edges) {
      if(a.colors.count(col)) append(a.unlocked_edges, v);
      else append(a.locked_edges[col], v);
    }
    for(int col : b.colors) unlock(a, col);
    b.locked_edges.clear();
    b.unlocked_edges.clear();
    b.nodes.clear();
    b.colors.clear();
  };

  auto find_edge = [&](info &a) {
    while(sz(a.unlocked_edges) && where[a.unlocked_edges.back()] == a.leader)
      a.unlocked_edges.pop_back();
    if(sz(a.unlocked_edges)) return a.unlocked_edges.back();
    return -1;
  };

  rep(x,0,n) comp[where[x]].nodes.emplace_back(x);
  rep(i,0,sz(u)) {
    int x = u[i], y = v[i], col = c[i];
    comp[where[x]].locked_edges[col].emplace_back(y);
    comp[where[y]].locked_edges[col].emplace_back(x);
  }

  rep(x,0,n) unlock(comp[where[x]], r[x]);


  auto deb = [&](){
    debug('%')
      rep(i,0,n) if(comp[i].leader == i) {
        //nassert(comp[i].leader == i);
        debug();
        debug(i);
        debug(comp[i].nodes);
        debug(comp[i].colors);
      }
  };

  //deb();


  vi done(n);
  vi in_st(n);
  vi st;

  int min_size = 1e9;

  function<void(int)> dfs = [&](int x) {
    x = where[x];
    if(done[x]) return;
    if(sz(comp[x].nodes) > min_size) return;
    if(in_st[x]) {
      while(st.back() != x) {
        int y = st.back();
        st.pop_back();
        in_st[y] = false;
        //assert(y == where[y]);
        join(where[x], y);
      }
      st.pop_back();
      x = where[x];
      in_st[x] = false;
    }

    st.emplace_back(x);
    in_st[x] = true;

    int y = find_edge(comp[x]);
    if(y == -1) {
      done[x] = true;
      min_size = min(min_size, sz(comp[x].nodes));
    }
    else dfs(y);
    done[x] = true;

  };

  rep(i,0,n) {
    dfs(i);
    for(int i : st) in_st[i] = false;
    st.clear();
  }

  vi p(n,1e9);
  rep(i,0,n) if(find_edge(comp[where[i]]) == -1)
    p[i] = sz(comp[where[i]].nodes);

  int mn = *min_element(all(p));
  vector<int> ans(n,0);
  rep(i,0,n) if(p[i] == mn) ans[i] = 1;

  return ans;
}

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

keys.cpp: In function 'std::vector<int> find_reachable(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
keys.cpp:84:8: warning: variable 'deb' set but not used [-Wunused-but-set-variable]
   84 |   auto deb = [&](){
      |        ^~~
#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...