結果

問題 No.382 シャイな人たち (2)
ユーザー Min_25Min_25
提出日時 2016-06-18 19:33:30
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 1,616 ms / 8,000 ms
コード長 5,151 bytes
コンパイル時間 804 ms
コンパイル使用メモリ 78,796 KB
実行使用メモリ 4,380 KB
最終ジャッジ日時 2023-07-31 01:53:01
合計ジャッジ時間 31,128 ms
ジャッジサーバーID
(参考情報)
judge15 / judge13
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1,614 ms
4,376 KB
testcase_01 AC 1,616 ms
4,380 KB
testcase_02 AC 1,409 ms
4,380 KB
testcase_03 AC 1,324 ms
4,376 KB
testcase_04 AC 1,321 ms
4,380 KB
testcase_05 AC 1,416 ms
4,380 KB
testcase_06 AC 1,144 ms
4,380 KB
testcase_07 AC 1,487 ms
4,380 KB
testcase_08 AC 1,163 ms
4,380 KB
testcase_09 AC 1,206 ms
4,376 KB
testcase_10 AC 1,301 ms
4,376 KB
testcase_11 AC 1,236 ms
4,376 KB
testcase_12 AC 1,293 ms
4,380 KB
testcase_13 AC 1,359 ms
4,380 KB
testcase_14 AC 1,452 ms
4,376 KB
testcase_15 AC 1,498 ms
4,376 KB
testcase_16 AC 1,326 ms
4,380 KB
testcase_17 AC 1,167 ms
4,380 KB
testcase_18 AC 1,481 ms
4,376 KB
testcase_19 AC 1,364 ms
4,376 KB
testcase_20 AC 2 ms
4,380 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>

#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <tuple>

#define _fetch(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _fetch(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)

using namespace std;

using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;

using u128 = __uint128_t;

const u32 N_MAX = 120;

int degs[N_MAX + 1];
u128 V_deg[N_MAX + 2];
u128 edges[N_MAX + 1];

inline int ctz(u128 n) {
  if (u64(n)) return __builtin_ctzll(u64(n));
  else return 64 + __builtin_ctzll(u64(n >> 64));
}

inline int pop_count(u128 n) {
  if (u64(n)) return __builtin_popcountll(u64(n));
  else return __builtin_popcountll(u64(n)) + __builtin_popcountll(u64(n >> 64));
}

inline void delete_v(u128 G, int v) {
  auto Nv = edges[v] & G;
  while (Nv) {
    auto fy = Nv & -Nv;
    int y = ctz(fy);
    V_deg[degs[y]--] ^= fy;
    V_deg[degs[y]] ^= fy;
    Nv ^= fy;
  }
}

inline void insert_v(u128 G, int v) {
  auto Nv = edges[v] & G;
  while (Nv) {
    auto fy = Nv & -Nv;
    int y = ctz(fy);
    V_deg[degs[y]++] ^= fy;
    V_deg[degs[y]] ^= fy;
    Nv ^= fy;
  }
}

inline void delete_Nv(u128 G, int v) {
  auto fv = u128(1) << v;
  auto Nv = fv ^ (edges[v] & G);
  while (Nv) {
    auto fy = Nv & -Nv;
    int y = ctz(fy);
    delete_v(G, y);
    Nv ^= fy;
  }
}

inline void insert_Nv(u128 G, int v) {
  auto fv = u128(1) << v;
  auto Nv = fv ^ (edges[v] & G);
  while (Nv) {
    auto fy = Nv & -Nv;
    int y = ctz(fy);
    insert_v(G, y);
    Nv ^= fy;
  }
}

// Naive: O(3^(n/3)) ~= O(1.4422^n)
int mis1(u128 G) {
  if (G == 0) return 0;
  for (int deg = 0; ; ++deg) if (V_deg[deg] & G) {
    int i_max = 0;
    auto fv = V_deg[deg] & G; fv &= -fv;
    int v = ctz(fv);
    auto Nv = (fv ^ edges[v]) & G;
    while (Nv) {
      auto fy = Nv & -Nv;
      int y = ctz(fy);
      auto Ny = (fy ^ edges[y]) & G;
      delete_v(G, y);
      i_max = max(i_max, mis1(G ^ Ny));
      insert_v(G, y);
      Nv ^= fy;
    }
    return 1 + i_max;
  }
}

// P(v, is_clique)
using P = pair<int, bool>;
inline P max_deg_vertex(u128 G, u128 S, int beg) {
  for (int deg = beg; ; ++deg) {
    u128 Vd = V_deg[deg] & G;
    if ((S |= Vd) != G) continue;
    auto fv = Vd & -Vd;
    int v = ctz(fv);
    return P(v, (Vd == G) && (pop_count(G) == deg + 1));
  }
}

int vertices[N_MAX];

// O(1.2905^n)
int mis3(u128 G, int idx=0) {
  if (G == 0) return 0;

  // d(v) <= 1
  const u128 V01 = (V_deg[0] | V_deg[1]) & G;
  if (V01) {
    auto fv = V01 & -V01;
    int v = ctz(fv);
    auto Nv = fv ^ (edges[v] & G);
    delete_Nv(G, v); vertices[idx] = v;
    int ret = 1 + mis3(G ^ Nv, idx + 1);
    insert_Nv(G, v);
    return ret;
  }

  // d(v) >= 3
  const u128 V2 = V_deg[2] & G;
  if (V2 != G) {
    auto p = max_deg_vertex(G, V2, 3);
    auto v = p.first;
    auto fv = u128(1) << v;
    if (p.second == true) {
      vertices[idx++] = v;
      return 1;
    } else {
      int vertices_back[N_MAX];

      // G / v
      delete_v(G, v);
      int ret = mis3(G ^ fv, idx); copy(vertices + idx, vertices + idx + ret, vertices_back);
      insert_v(G, v);

      // G / N(v)
      auto Nv = fv ^ (edges[v] & G);
      delete_Nv(G, v); vertices[idx] = v;
      int ret2 = 1 + mis3(G ^ Nv, idx + 1);
      insert_Nv(G, v);

      if (ret > ret2) {
        copy(vertices_back, vertices_back + ret, vertices + idx);
      } else {
        ret = ret2;
      }
      return ret;
    }
  }

  // Delta(G) = delta(G) = 2
  int ret = 0;
  while (G) {
    auto fv = G & -G;
    int cycle_len = 0;
    for (; fv; ++cycle_len) {
      int v = ctz(fv);
      G ^= fv;
      fv = edges[v] & G; fv &= -fv;
      if (cycle_len & 1) vertices[idx++] = v;
    }
    ret += cycle_len / 2;
  }
  return ret;
}

struct Rand {
  Rand(u32 seed) : x(seed) {}
  u32 next() { return x = u64(x) * 12345 % 1000003; }
  u32 x;
};

u128 set_graph(int S) {
  auto gene = Rand(S);
  int N = gene.next() % N_MAX + 2;
  int P = gene.next();
  // fprintf(stderr, "N: %u, P: %u\n", N, P);
  rep(i, N) {
    degs[i] = V_deg[i] = edges[i] = 0;
  }
  rep(i, N) rep(j, i + 1, N) {
    int X = gene.next();
    if (X >= P) {
      edges[i] |= u128(1) << j; degs[i]++;
      edges[j] |= u128(1) << i; degs[j]++;
      // fprintf(stderr, "E: %u <-> %u (%u)\n", i, j, X);
    }
  }
  rep(i, N) V_deg[degs[i]] |= u128(1) << i;
  u128 G = (u128(1) << N) - 1;
  return G;
}

void solve() {
  int S;
  while (~scanf("%d", &S)) {
    u128 G = set_graph(S);
    int len = mis3(G);
    if (len == pop_count(G)) {
      puts("-1");
    } else {
      printf("%u\n", len + 1);
      rep(i, len) {
        if (i) putchar(' ');
        printf("%u", vertices[i] + 1);
      }
      puts("");
    }
  }
}

int main() {
  clock_t beg = clock();
  solve();
  clock_t end = clock();
  fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
  return 0;
}
0