Submission #35069435


Source Code Expand

// O(N^2) 辺 + 密グラフ Dinic
#include <bits/stdc++.h>
#include <atcoder/dsu>
#include <atcoder/scc>

namespace atcoder {

namespace internal {

template <class T> struct simple_queue {
    std::vector<T> payload;
    int pos = 0;
    void reserve(int n) { payload.reserve(n); }
    int size() const { return int(payload.size()) - pos; }
    bool empty() const { return pos == int(payload.size()); }
    void push(const T& t) { payload.push_back(t); }
    T& front() { return payload[pos]; }
    void clear() {
        payload.clear();
        pos = 0;
    }
    void pop() { pos++; }
};

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class Cap> struct mf_graph {
  public:
    mf_graph() : _n(0) {}
    explicit mf_graph(int n) : _n(n), g(n, std::vector<bool>(n)) {}

    void add_edge(int from, int to) {
        g[from][to] = true;
    }

    Cap flow(int s, int t) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        std::vector<int> level(_n), iter(_n);
        internal::simple_queue<int> que;

        auto bfs = [&]() {
            std::fill(level.begin(), level.end(), -1);
            level[s] = 0;
            que.clear();
            que.push(s);
            while (!que.empty()) {
                int v = que.front();
                que.pop();
                for (int i = 0; i < _n; i++) {
                    if (!g[v][i] || level[i] >= 0) continue;
                    level[i] = level[v] + 1;
                    if (i == t) return;
                    que.push(i);
                }
            }
        };

        auto dfs = [&](auto dfs, int v) -> bool {
            if (v == s) return true;
            int level_v = level[v];
            for (int& i = iter[v]; i < _n; i++) {
                if (!g[i][v] || level_v <= level[i]) continue;
                const bool d = dfs(dfs, i);
                if (!d) continue;
                g[v][i] = true;
                g[i][v] = false;
                return true;
            }
            level[v] = _n;
            return false;
        };

        auto dfs_first = [&](int v) -> Cap {
            Cap res = 0;
            int level_v = level[v];
            for (int& i = iter[v]; i < _n; i++) {
                if (!g[i][v] || level_v <= level[i]) continue;
                const bool d = dfs(dfs, i);
                if (!d) continue;
                g[v][i] = true;
                g[i][v] = false;
                res++;
            }
            level[v] = _n;
            return res;
        };

        Cap flow = 0;
        while (true) {
            bfs();
            if (level[t] == -1) break;
            std::fill(iter.begin(), iter.end(), 0);
            Cap f = dfs_first(t);
            if (!f) break;
            flow += f;
        }
        return flow;
    }

    int _n;
    std::vector<std::vector<bool>> g;
};

}  // namespace atcoder

using namespace std;
using u64 = uint64_t;


vector<int> solve(int N, vector<pair<int, int>> edge){
    sort(edge.begin(), edge.end());
    const int S = N * 2, T = S + 1;
    atcoder::mf_graph<int> g(T + 1);
    for(int i = 0; i < N; i++){
        g.add_edge(S, i);
        g.add_edge(N + i, T);
    }
    for(int ii = 0; ii < N; ii += 64){
        vector<u64> bit(N);
        for(int i = 0; i < min(N - ii, 64); i++){
            bit[ii + i] |= u64{1} << i;
        }
        for(auto& [A, B] : edge) bit[B] |= bit[A];
        for(int i = 0; i < min(N - ii, 64); i++){
            bit[ii + i] ^= u64{1} << i;
        }
        for(int j = ii; j < N; j++) for(int i = 0; i < 64; i++) if(bit[j] & u64{1} << i){
            g.add_edge(ii + i, N + j);
        }
    }
    g.flow(S, T);
    atcoder::dsu uf(N);
    for(int i = 0; i < N; i++) for(int j = 0; j < N; j++){
        if(g.g[N + j][i]) uf.merge(i, j);
    }
    unordered_map<int, int> color;
    vector<int> answer(N);
    for(int i = 0; i < N; i++) answer[i] = color.try_emplace(uf.leader(i), color.size()).first->second;
    return answer;
}
int main(){
    cin.tie(0)->sync_with_stdio(0);
    int N, M;
    cin >> N >> M;
    vector<pair<int, int>> edge(M);
    atcoder::scc_graph g(N);
    for(auto& [A, B] : edge){
        cin >> A >> B;
        A--; B--;
        g.add_edge(A, B);
    }
    auto scc = g.scc();
    const int n = scc.size();
    vector<int> idx(N);
    for(int i = 0; i < n; i++) for(int j : scc[i]) idx[j] = i;
    for(auto& [A, B] : edge){
        A = idx[A];
        B = idx[B];
        assert(A <= B);
    }
    edge.erase(remove_if(edge.begin(), edge.end(), [](pair<int, int> a){ return a.first == a.second; }), edge.end());
    auto color = solve(n, move(edge));
    vector<int> answer(N);
    for(int i = 0; i < N; i++) cout << color[idx[i]] + 1 << " \n"[i + 1 == N];
}

Submission Info

Submission Time
Task H - Colorful Graph
User tatyam
Language C++ (GCC 9.2.1)
Score 300
Code Size 4783 Byte
Status AC
Exec Time 4438 ms
Memory 28984 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 300 / 300
Status
AC × 3
AC × 31
Set Name Test Cases
Sample sample-01.txt, sample-02.txt, sample-03.txt
All killer-01.txt, killer-02.txt, killer-03.txt, killer-shobon-01.txt, killer-shobon-02.txt, max-00.txt, path-01.txt, path-02.txt, path-03.txt, path-04.txt, path-05.txt, random-01.txt, random-02.txt, random-03.txt, random-04.txt, random-05.txt, random-dag-01.txt, random-dag-02.txt, random-dag-03.txt, random-dag-04.txt, random-dag-05.txt, sample-01.txt, sample-02.txt, sample-03.txt, small-01.txt, small-02.txt, small-03.txt, small-04.txt, small-05.txt, small-06.txt, star-01.txt
Case Name Status Exec Time Memory
killer-01.txt AC 1971 ms 28860 KiB
killer-02.txt AC 971 ms 28856 KiB
killer-03.txt AC 2029 ms 28844 KiB
killer-shobon-01.txt AC 968 ms 28948 KiB
killer-shobon-02.txt AC 942 ms 28556 KiB
max-00.txt AC 318 ms 28396 KiB
path-01.txt AC 1001 ms 28984 KiB
path-02.txt AC 142 ms 8552 KiB
path-03.txt AC 105 ms 7292 KiB
path-04.txt AC 502 ms 15720 KiB
path-05.txt AC 838 ms 23004 KiB
random-01.txt AC 4209 ms 28564 KiB
random-02.txt AC 4190 ms 28432 KiB
random-03.txt AC 4438 ms 27676 KiB
random-04.txt AC 3249 ms 21596 KiB
random-05.txt AC 17 ms 4016 KiB
random-dag-01.txt AC 3773 ms 28552 KiB
random-dag-02.txt AC 3824 ms 28672 KiB
random-dag-03.txt AC 2936 ms 28172 KiB
random-dag-04.txt AC 2651 ms 23796 KiB
random-dag-05.txt AC 585 ms 7824 KiB
sample-01.txt AC 2 ms 3408 KiB
sample-02.txt AC 2 ms 3568 KiB
sample-03.txt AC 1 ms 3408 KiB
small-01.txt AC 2 ms 3588 KiB
small-02.txt AC 4 ms 3528 KiB
small-03.txt AC 3 ms 3508 KiB
small-04.txt AC 2 ms 3508 KiB
small-05.txt AC 4 ms 3496 KiB
small-06.txt AC 2 ms 3412 KiB
star-01.txt AC 1091 ms 28644 KiB