提出 #22050182


ソースコード 拡げる

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld  = long double;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
const int INF=1e9+7;
const ll LINF=9223372036854775807;
const ll MOD=1e9+7;
const ld PI=acos(-1);
const ld EPS = 1e-10; //微調整用(EPSより小さいと0と判定など)

int ii() { int x; if (scanf("%d", &x)==1) return x; else return 0; }
long long il() { long long x; if (scanf("%lld", &x)==1) return x; else return 0; }
string is() { string x; cin >> x; return x; }
char ic() { char x; cin >> x; return x; }
void oi(int x) { printf("%d ", x); }
void ol(long long x) { printf("%lld ", x); }
void od_nosp(double x) { printf("%.15f", x); } // 古い問題用
void od(double x) { printf("%.15f ", x); }
void os(const string &s) { printf("%s ", s.c_str()); }
void oc(const char &c) { printf("%c ", c); }
#define o_map(v){cerr << #v << endl; for(const auto& xxx: v){cout << xxx.first << " " << xxx.second << "ddddddddd\n";}} //動作未確認
void br() { putchar('\n'); }

// #define gcd __gcd //llは受け取らない C++17~のgcdと違うので注意
// int lcm(int a, int b){return a / gcd(a, b) * b;}
#define b_e(a) a.begin(),a.end() //sort(b_e(vec));
#define REP(i,m,n) for(ll i=(ll)(m) ; i < (ll)(n) ; i++ )
#define DREP(i,m,n) for(ll i=(ll)(m) ; i > (ll)(n) ; i-- )
#define rep(i,n) REP(i,0,n)
#define m_p(a,b) make_pair(a,b)
#define p_b push_back
#define SZ(x) ((ll)(x).size()) //size()がunsignedなのでエラー避けに
#define endk '\n'


// coutによるpairの出力(空白区切り)
template<typename T1, typename T2> ostream& operator<<(ostream& s, const pair<T1, T2>& p) {return s << "(" << p.first << " " << p.second << ")";}
// coutによるvectorの出力(空白区切り)
template<typename T> ostream& operator<<(ostream& s, const vector<T>& v) {
  int len = v.size();
  for (int i = 0; i < len; ++i) {
    s << v[i]; if (i < len - 1) s << " "; //"\t"に変えるとTabで見やすく区切る
  }
  return s;
}
// coutによる多次元vectorの出力(空白区切り)
template<typename T> ostream& operator<<(ostream& s, const vector< vector<T> >& vv) {
  int len = vv.size();
  for (int i = 0; i < len; ++i) {
    s << vv[i] << endl;
  }
  return s;
}

//最大値、最小値の更新。更新したor等しければtrueを返す
template<typename T>
bool chmax(T& a, T b){return (a = max(a, b)) == b;}
template<typename T>
bool chmin(T& a, T b){return (a = min(a, b)) == b;}

//4近傍(上下左右) rep(i, 2) にすると右・下だけに進む
vector<int> dx_4 = {1, 0, -1, 0};
vector<int> dy_4 = {0, 1, 0, -1};

// -------- template end - //


// - library ------------- //

// #include <atcoder/all>
#include <atcoder/all>
using namespace atcoder;

// 10^18まではいけるようだが、10^19でオーバーフローする
// MODをつけたい場合もこれでもいい
// 繰り返し二乗法を使っているので O(logN) で計算できる
ll llpow(ll x, ll n){
  ll ans = 1;
  while (n > 0){
    if (n % 2 == 1) ans = ans * x; // % MOD; (MODつけたい場合のコピー用)
    x = x * x; // % MOD; (MODつけたい場合のコピー用)
    n /= 2; // n を右に1つビットシフト
  }
  return ans;
}


using Graph = vector<vector<ll>>;
bool is_bipartite_graph(const Graph &graph, vector<ll> &colors, int v, int c, ll &cnt) {
  if (colors[v] != -1) return true; // 無色じゃなければ無視

  // 無色なら、そこを塗って次へ行く
  cnt++;
  colors[v] = c;
  for (int u: graph[v]) {
    if (colors[u] == c) {
      return false;
    }
    if (colors[u] == -1 && !is_bipartite_graph(graph, colors, u, (c+1)%2, cnt)) {
      return false;
    }
  }
  return true;
}


// --------- library end - //




int main(){

  ll N, M;
  cin >> N >> M;

  vector<pll> edges(M); // 赤同士が隣接しないかの判定のため
  Graph adjs(N); // 隣接リスト表現
  vector<bool> seen(N, false);

  // adjs の作成
  rep(i, M){
    ll a, b;
    cin >> a >> b;
    a--; b--; // 0-indexed
    adjs[a].p_b(b);
    adjs[b].p_b(a); // undirected

    edges[i] = pll(a, b); // 赤同士が隣接しないかの判定のため
  }

  // 赤色で決め打つ箇所を bit 全探索 -> 決め打たなかった頂点を二部グラフ判定
  // 二部グラフであれば、緑・青で塗り分けられる
  // 塗り分け方の通り数は 2^(赤以外の頂点をグラフとしたときの連結成分数)
  
  // N個の要素 {0, 1, ..., n-1} の部分集合の全探索
  // colors[i] := -1:無色, 2:赤, 0:緑, 1:青
  ll ans = 0;
  for (ll bit = 0; bit < (1LL<<N); ++bit){
    vector<ll> colors(N, -1);
    rep(i, N){
      if (bit & (1LL<<i)){  // i番目のbitがtrue -> 赤で塗る
        colors[i] = 2;
      }
    }

    // 赤の頂点が隣接しているとNGなので、隣接頂点が赤同士でないか判定
    bool ng = false;
    for (pll p : edges){
      if (colors[p.first] == 2 && colors[p.second] == 2){
        ng = true;
        break;
      }
    }
    if (ng) continue;

    // 二部グラフ判定
    // なお、無色頂点が見つかった回数を cnt とする。cnt>0であれば二部グラフ判定の起点となった頂点なので、連結成分数を+1する
    ll cc_cnt = 0;
    bool is_bipartite = true;
    rep(i, N){
      ll cnt = 0;
      if (!is_bipartite_graph(adjs, colors, i, 0, cnt)){
        is_bipartite = false;
        break;
      }
      if (cnt > 0) cc_cnt++;
    }
    if (is_bipartite) ans += llpow(2, cc_cnt);
  }

  cout << ans << endk;

}

提出情報

提出日時
問題 D - RGB Coloring 2
ユーザ TeruMiyake
言語 C++ (GCC 9.2.1)
得点 400
コード長 5725 Byte
結果 AC
実行時間 232 ms
メモリ 3544 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 400 / 400
結果
AC × 4
AC × 48
セット名 テストケース
Sample sample_01.txt, sample_02.txt, sample_03.txt, sample_04.txt
All few_hen_00.txt, few_hen_01.txt, few_hen_02.txt, few_hen_03.txt, few_hen_04.txt, few_hen_05.txt, few_hen_06.txt, few_hen_07.txt, manual_00.txt, manual_01.txt, manual_02.txt, random_00.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, sample_01.txt, sample_02.txt, sample_03.txt, sample_04.txt, tree_00.txt, tree_01.txt, tree_02.txt, tree_03.txt, tree_04.txt, tree_05.txt, tree_06.txt, tree_07.txt, tree_08.txt
ケース名 結果 実行時間 メモリ
few_hen_00.txt AC 125 ms 3444 KiB
few_hen_01.txt AC 123 ms 3448 KiB
few_hen_02.txt AC 116 ms 3540 KiB
few_hen_03.txt AC 127 ms 3444 KiB
few_hen_04.txt AC 118 ms 3464 KiB
few_hen_05.txt AC 118 ms 3444 KiB
few_hen_06.txt AC 152 ms 3396 KiB
few_hen_07.txt AC 122 ms 3372 KiB
manual_00.txt AC 2 ms 3484 KiB
manual_01.txt AC 2 ms 3436 KiB
manual_02.txt AC 1 ms 3436 KiB
random_00.txt AC 101 ms 3504 KiB
random_01.txt AC 110 ms 3376 KiB
random_02.txt AC 109 ms 3428 KiB
random_03.txt AC 100 ms 3420 KiB
random_04.txt AC 101 ms 3440 KiB
random_05.txt AC 102 ms 3488 KiB
random_06.txt AC 106 ms 3420 KiB
random_07.txt AC 98 ms 3448 KiB
random_08.txt AC 103 ms 3536 KiB
random_09.txt AC 109 ms 3544 KiB
random_10.txt AC 110 ms 3440 KiB
random_11.txt AC 111 ms 3464 KiB
random_12.txt AC 2 ms 3460 KiB
random_13.txt AC 2 ms 3500 KiB
random_14.txt AC 2 ms 3460 KiB
random_15.txt AC 19 ms 3500 KiB
random_16.txt AC 2 ms 3444 KiB
random_17.txt AC 3 ms 3400 KiB
random_18.txt AC 23 ms 3400 KiB
random_19.txt AC 61 ms 3504 KiB
random_20.txt AC 103 ms 3456 KiB
random_21.txt AC 57 ms 3400 KiB
random_22.txt AC 2 ms 3536 KiB
random_23.txt AC 7 ms 3536 KiB
sample_01.txt AC 2 ms 3500 KiB
sample_02.txt AC 2 ms 3460 KiB
sample_03.txt AC 3 ms 3440 KiB
sample_04.txt AC 232 ms 3372 KiB
tree_00.txt AC 154 ms 3492 KiB
tree_01.txt AC 101 ms 3492 KiB
tree_02.txt AC 110 ms 3464 KiB
tree_03.txt AC 194 ms 3440 KiB
tree_04.txt AC 112 ms 3484 KiB
tree_05.txt AC 114 ms 3500 KiB
tree_06.txt AC 195 ms 3488 KiB
tree_07.txt AC 105 ms 3464 KiB
tree_08.txt AC 108 ms 3396 KiB