Submission #19495216


Source Code Expand

Copy
//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
//#include <atcoder/all>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set = tree<T, null_type, std::less<T>, rb_tree_tag, tree_order_statistics_node_update>;
using namespace std;
#define all(n) begin(n), end(n)
const long long INF = INT_MAX / 2;
typedef long long ll;
typedef vector<int> vint;
typedef vector<vector<int>> vvint;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef unsigned long long ull;
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts)
{
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v)
{
    for (auto &e : t)
        fill_v(e, v);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    // 解法
    // 与えられたグラフを G = (V,E) とする
    // 頂点集合 V を半分に分割する。それを V_1,V_2 とおく
    // V_1 の部分集合を列挙する(たかだか2^20個)
    // S_1 ⊂ V_1 に対して、S_1 が独立集合かどうかを判定する ... (1)
    // もしそうなら、S_1 の任意の点と繋がっていないような V_2 の頂点全体を U とする ... (2)
    // U の最大独立集合を求めて ... (3) 、それを S_2 とする
    // max { |S_1| + |S_2| } がこたえ

    // (1) bitDPでできる。 dp[S] := S が独立集合のとき、かつその時に限り true とする. true で初期化しておく
    // (v,u) ∈ E , v,u ∈ V_1 に対し、 dp[{v,u}] = false

    // 遷移 : dp[S] = false のとき、 任意の v ∈ V_1 \ S に対して dp[S ⋃ {v}] = false

    // (2) これも bitDP でできる。 dp[S] := S の任意の点と繋がっていないような V_2 の頂点全体の集合 とすると
    // dp[{}] = V_2
    // dp[{v}] = V_2 \ {u | u ∈ V_2, (v,u) ∈ E}
    // dp[S ⋃ {v}] = dp[S] \ {u | u ∈ V_2, (v,u) ∈ E} = dp[S] ⋂ dp[{v}]

    // (3) これも bitDP でできる。 dp[S] := S の最大独立集合のサイズ とすると、
    // dp[S] = if S が独立集合 then |S| else 0
    // と初期化しておいて、
    // dp[S ⋃ {v}] = max(dp[S ⋃ {v}],dp[S]) としたらよい
    int n, m;
    cin >> n >> m;
    int n1 = n / 2, n2 = n - n1; // V_1 と V_2 のサイズ
    const int MAX = 1 << 20;
    vector<bool> is_independ1(MAX, true), is_independ2(MAX, true);
    vector<int> disjoint_set(MAX);
    vector<int> independ_size(MAX);

    vint a(m), b(m);
    for (int i = 0; i < m; i++)
    {
        cin >> a[i] >> b[i];
        a[i]--;
        b[i]--;
        if (a[i] < n1 and b[i] < n1)
        {
            is_independ1[(1 << a[i]) | (1 << b[i])] = false;
        }
        if (a[i] >= n1 and b[i] >= n1)
        {
            is_independ2[(1 << (a[i] - n1)) | (1 << (b[i] - n1))] = false;
        }
    }
    for (int bit = 0; bit < (1 << n1); bit++)
    {
        if (!is_independ1[bit])
        {
            for (int i = 0; i < n1; i++)
            {
                is_independ1[bit | (1 << i)] = false;
            }
        }
    }
    for (int bit = 0; bit < (1 << n2); bit++)
    {
        if (!is_independ2[bit])
        {
            for (int i = 0; i < n2; i++)
            {
                is_independ2[bit | (1 << i)] = false;
            }
        }
    }
    disjoint_set[0] = (1 << n2) - 1;
    for (int i = 0; i < n1; i++)
    {
        disjoint_set[(1 << i)] = disjoint_set[0];
        for (int j = 0; j < m; j++)
        {
            if (a[j] == i and b[j] >= n1)
            {
                disjoint_set[(1 << i)] &= ~(1 << (b[j] - n1));
            }
            else if (b[j] == i and a[j] >= n1)
            {
                disjoint_set[(1 << i)] &= ~(1 << (a[j] - n1));
            }
        }
    }
    for (int bit = 0; bit < (1 << n2); bit++)
    {
        for (int i = 0; i < n2; i++)
        {
            disjoint_set[bit | (1 << i)] = disjoint_set[bit] & disjoint_set[(1 << i)];
        }
    }
    for (int bit = 0; bit < (1 << n2); bit++)
    {
        if (is_independ2[bit])
            independ_size[bit] = __builtin_popcount(bit);
    }
    for (int bit = 0; bit < (1 << n2); bit++)
    {
        for (int i = 0; i < n2; i++)
        {
            chmax(independ_size[bit | (1 << i)], independ_size[bit]);
        }
    }
    int ans = 0;
    for (int bit = 0; bit < (1 << n1); bit++)
    {
        if (is_independ1[bit])
        {
            int u = disjoint_set[bit];
            int s1 = __builtin_popcount(bit), s2 = independ_size[u];
            chmax(ans, s1 + s2);
        }
    }
    cout << ans << endl;
    return 0;
}

Submission Info

Submission Time
Task G - Mixture Drug
User shift0
Language C++ (GCC 9.2.1)
Score 600
Code Size 5326 Byte
Status AC
Exec Time 130 ms
Memory 11648 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 600 / 600
Status
AC × 3
AC × 51
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All sample_01.txt, sample_02.txt, sample_03.txt, subtask_1_1.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_12.txt, subtask_1_13.txt, subtask_1_14.txt, subtask_1_15.txt, subtask_1_16.txt, subtask_1_17.txt, subtask_1_18.txt, subtask_1_19.txt, subtask_1_2.txt, subtask_1_20.txt, subtask_1_21.txt, subtask_1_22.txt, subtask_1_23.txt, subtask_1_24.txt, subtask_1_25.txt, subtask_1_26.txt, subtask_1_27.txt, subtask_1_28.txt, subtask_1_29.txt, subtask_1_3.txt, subtask_1_30.txt, subtask_1_31.txt, subtask_1_32.txt, subtask_1_33.txt, subtask_1_34.txt, subtask_1_35.txt, subtask_1_36.txt, subtask_1_37.txt, subtask_1_38.txt, subtask_1_39.txt, subtask_1_4.txt, subtask_1_40.txt, subtask_1_41.txt, subtask_1_42.txt, subtask_1_43.txt, subtask_1_44.txt, subtask_1_45.txt, subtask_1_46.txt, subtask_1_47.txt, subtask_1_48.txt, subtask_1_5.txt, subtask_1_6.txt, subtask_1_7.txt, subtask_1_8.txt, subtask_1_9.txt
Case Name Status Exec Time Memory
sample_01.txt AC 13 ms 11648 KB
sample_02.txt AC 12 ms 11496 KB
sample_03.txt AC 13 ms 11504 KB
subtask_1_1.txt AC 20 ms 11648 KB
subtask_1_10.txt AC 126 ms 11608 KB
subtask_1_11.txt AC 15 ms 11432 KB
subtask_1_12.txt AC 125 ms 11472 KB
subtask_1_13.txt AC 90 ms 11432 KB
subtask_1_14.txt AC 97 ms 11616 KB
subtask_1_15.txt AC 11 ms 11492 KB
subtask_1_16.txt AC 116 ms 11648 KB
subtask_1_17.txt AC 122 ms 11608 KB
subtask_1_18.txt AC 128 ms 11476 KB
subtask_1_19.txt AC 12 ms 11628 KB
subtask_1_2.txt AC 90 ms 11548 KB
subtask_1_20.txt AC 116 ms 11616 KB
subtask_1_21.txt AC 122 ms 11644 KB
subtask_1_22.txt AC 126 ms 11544 KB
subtask_1_23.txt AC 12 ms 11524 KB
subtask_1_24.txt AC 21 ms 11472 KB
subtask_1_25.txt AC 126 ms 11492 KB
subtask_1_26.txt AC 126 ms 11596 KB
subtask_1_27.txt AC 126 ms 11628 KB
subtask_1_28.txt AC 129 ms 11588 KB
subtask_1_29.txt AC 125 ms 11604 KB
subtask_1_3.txt AC 38 ms 11572 KB
subtask_1_30.txt AC 12 ms 11476 KB
subtask_1_31.txt AC 11 ms 11648 KB
subtask_1_32.txt AC 16 ms 11492 KB
subtask_1_33.txt AC 17 ms 11644 KB
subtask_1_34.txt AC 116 ms 11520 KB
subtask_1_35.txt AC 127 ms 11644 KB
subtask_1_36.txt AC 129 ms 11592 KB
subtask_1_37.txt AC 127 ms 11552 KB
subtask_1_38.txt AC 126 ms 11548 KB
subtask_1_39.txt AC 130 ms 11596 KB
subtask_1_4.txt AC 127 ms 11520 KB
subtask_1_40.txt AC 124 ms 11600 KB
subtask_1_41.txt AC 126 ms 11544 KB
subtask_1_42.txt AC 125 ms 11648 KB
subtask_1_43.txt AC 120 ms 11644 KB
subtask_1_44.txt AC 119 ms 11500 KB
subtask_1_45.txt AC 117 ms 11576 KB
subtask_1_46.txt AC 98 ms 11556 KB
subtask_1_47.txt AC 123 ms 11576 KB
subtask_1_48.txt AC 113 ms 11604 KB
subtask_1_5.txt AC 44 ms 11648 KB
subtask_1_6.txt AC 125 ms 11548 KB
subtask_1_7.txt AC 59 ms 11604 KB
subtask_1_8.txt AC 123 ms 11436 KB
subtask_1_9.txt AC 69 ms 11596 KB