kyopro-lib

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

View on GitHub

:question: Graph vertex coloring
(Mylib/Graph/Coloring/chromatic_number.cpp)

Operations

Requirements

Notes

Problems

References

Depends on

Verified with

Code

#pragma once
#include <cmath>
#include <cstdint>
#include <vector>
#include "Mylib/Number/Mod/mod_pow.cpp"

namespace haar_lib {
  int chromatic_number(const std::vector<std::vector<int>> &graph) {
    static constexpr int mod = 1000000007;
    const int N              = graph.size();

    std::vector<int> g(N);
    for (int i = 0; i < N; ++i) {
      for (auto j : graph[i]) {
        g[i] |= (1 << j);
      }
    }

    std::vector<int64_t> I(1 << N);
    I[0] = 1;
    for (int i = 1; i < (1 << N); ++i) {
      int c = __builtin_ctz(i);
      I[i]  = I[i - (1 << c)] + I[(i - (1 << c)) & (~g[c])];
      if (I[i] >= mod) I[i] -= mod;
    }

    const auto check =
        [&](int k) {
          int64_t t = 0;
          for (int i = 0; i < (1 << N); ++i) {
            if (__builtin_popcount(i) % 2 == 1)
              t -= mod_pow(I[i], k, mod);
            else
              t += mod_pow(I[i], k, mod);
            if (t < 0) t += mod;
            if (t >= mod) t -= mod;
          }
          return (t % mod != 0);
        };

    int lb = 0, ub = N;
    while (std::abs(lb - ub) > 1) {
      const auto mid = (lb + ub) / 2;

      if (check(mid)) {
        ub = mid;
      } else {
        lb = mid;
      }
    }

    return ub;
  }
}  // namespace haar_lib
#line 2 "Mylib/Graph/Coloring/chromatic_number.cpp"
#include <cmath>
#include <cstdint>
#include <vector>
#line 3 "Mylib/Number/Mod/mod_pow.cpp"

namespace haar_lib {
  constexpr int64_t mod_pow(int64_t n, int64_t p, int64_t m) {
    int64_t ret = 1;
    while (p > 0) {
      if (p & 1) (ret *= n) %= m;
      (n *= n) %= m;
      p >>= 1;
    }
    return ret;
  }
}  // namespace haar_lib
#line 6 "Mylib/Graph/Coloring/chromatic_number.cpp"

namespace haar_lib {
  int chromatic_number(const std::vector<std::vector<int>> &graph) {
    static constexpr int mod = 1000000007;
    const int N              = graph.size();

    std::vector<int> g(N);
    for (int i = 0; i < N; ++i) {
      for (auto j : graph[i]) {
        g[i] |= (1 << j);
      }
    }

    std::vector<int64_t> I(1 << N);
    I[0] = 1;
    for (int i = 1; i < (1 << N); ++i) {
      int c = __builtin_ctz(i);
      I[i]  = I[i - (1 << c)] + I[(i - (1 << c)) & (~g[c])];
      if (I[i] >= mod) I[i] -= mod;
    }

    const auto check =
        [&](int k) {
          int64_t t = 0;
          for (int i = 0; i < (1 << N); ++i) {
            if (__builtin_popcount(i) % 2 == 1)
              t -= mod_pow(I[i], k, mod);
            else
              t += mod_pow(I[i], k, mod);
            if (t < 0) t += mod;
            if (t >= mod) t -= mod;
          }
          return (t % mod != 0);
        };

    int lb = 0, ub = N;
    while (std::abs(lb - ub) > 1) {
      const auto mid = (lb + ub) / 2;

      if (check(mid)) {
        ub = mid;
      } else {
        lb = mid;
      }
    }

    return ub;
  }
}  // namespace haar_lib
Back to top page