Luzhiled's Library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ei1333/library

:heavy_check_mark: Maximum Clique(最大クリーク)
(graph/others/maximum-clique.hpp)

Verified with

Code

#pragma once

/**
 * @brief Maximum Clique(最大クリーク)
 */
template< int V >
struct MaximumClique {
  using B = bitset< V >;
  vector< B > g, col_buf;

  struct P {
    int idx, col, deg;

    P(int idx, int col, int deg) : idx(idx), col(col), deg(deg) {}
  };

  MaximumClique() = default;

  explicit MaximumClique(int N) : g(N), col_buf(N) {}

  void add_edge(int a, int b) {
    g[a].set(b);
    g[b].set(a);
  }

  vector< int > now, clique;

  void dfs(vector< P > &rem) {
    if(clique.size() < now.size()) clique = now;
    sort(begin(rem), end(rem), [](const P &a, const P &b) {
      return a.deg > b.deg;
    });
    int max_c = 1;
    for(auto &p : rem) {
      p.col = 0;
      while((g[p.idx] & col_buf[p.col]).any()) ++p.col;
      max_c = max(max_c, p.idx + 1);
      col_buf[p.col].set(p.idx);
    }
    for(int i = 0; i < max_c; i++) col_buf[i].reset();
    sort(begin(rem), end(rem), [&](const P &a, const P &b) {
      return a.col < b.col;
    });
    for(; !rem.empty(); rem.pop_back()) {
      auto &p = rem.back();
      if(now.size() + p.col + 1 <= clique.size()) break;
      vector< P > nrem;
      B bs;
      for(auto &q : rem) {
        if(g[p.idx][q.idx]) {
          nrem.emplace_back(q.idx, -1, 0);
          bs.set(q.idx);
        }
      }
      for(auto &q : nrem) {
        q.deg = (bs & g[q.idx]).count();
      }
      now.emplace_back(p.idx);
      dfs(nrem);
      now.pop_back();
    }
  }

  vector< int > solve() {
    vector< P > remark;
    for(size_t i = 0; i < g.size(); i++) {
      remark.emplace_back(i, -1, (int) g[i].size());
    }
    dfs(remark);
    return clique;
  }
};
#line 2 "graph/others/maximum-clique.hpp"

/**
 * @brief Maximum Clique(最大クリーク)
 */
template< int V >
struct MaximumClique {
  using B = bitset< V >;
  vector< B > g, col_buf;

  struct P {
    int idx, col, deg;

    P(int idx, int col, int deg) : idx(idx), col(col), deg(deg) {}
  };

  MaximumClique() = default;

  explicit MaximumClique(int N) : g(N), col_buf(N) {}

  void add_edge(int a, int b) {
    g[a].set(b);
    g[b].set(a);
  }

  vector< int > now, clique;

  void dfs(vector< P > &rem) {
    if(clique.size() < now.size()) clique = now;
    sort(begin(rem), end(rem), [](const P &a, const P &b) {
      return a.deg > b.deg;
    });
    int max_c = 1;
    for(auto &p : rem) {
      p.col = 0;
      while((g[p.idx] & col_buf[p.col]).any()) ++p.col;
      max_c = max(max_c, p.idx + 1);
      col_buf[p.col].set(p.idx);
    }
    for(int i = 0; i < max_c; i++) col_buf[i].reset();
    sort(begin(rem), end(rem), [&](const P &a, const P &b) {
      return a.col < b.col;
    });
    for(; !rem.empty(); rem.pop_back()) {
      auto &p = rem.back();
      if(now.size() + p.col + 1 <= clique.size()) break;
      vector< P > nrem;
      B bs;
      for(auto &q : rem) {
        if(g[p.idx][q.idx]) {
          nrem.emplace_back(q.idx, -1, 0);
          bs.set(q.idx);
        }
      }
      for(auto &q : nrem) {
        q.deg = (bs & g[q.idx]).count();
      }
      now.emplace_back(p.idx);
      dfs(nrem);
      now.pop_back();
    }
  }

  vector< int > solve() {
    vector< P > remark;
    for(size_t i = 0; i < g.size(); i++) {
      remark.emplace_back(i, -1, (int) g[i].size());
    }
    dfs(remark);
    return clique;
  }
};
Back to top page