cp-documentation

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

View the Project on GitHub zawa-tin/cp-documentation

:heavy_check_mark: Test/LC/rooted_tree_isomorphism_classification.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/rooted_tree_isomorphism_classification"

#include "../../Src/Graph/Tree/SubtreesHash.hpp"

#include <algorithm>
#include <iostream>
#include <vector>

using namespace zawa;

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int N;
    std::cin >> N;
    std::vector<std::vector<int>> g(N);
    for (int i = 1 ; i < N ; i++) {
        int p;
        std::cin >> p;
        g[p].push_back(i);
    }
    auto ans = SubtreesHasher{}(g);
    auto K = *std::max_element(ans.begin(), ans.end()) + 1;
    std::cout << K << '\n';
    for (int i = 0 ; i < N ; i++) std::cout << ans[i] << (i + 1 == N ? '\n' : ' ');
}
#line 1 "Test/LC/rooted_tree_isomorphism_classification.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/rooted_tree_isomorphism_classification"

#line 2 "Src/Graph/Tree/SubtreesHash.hpp"

#line 2 "Src/Template/TypeAlias.hpp"

#include <cstdint>
#include <cstddef>

namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa
#line 4 "Src/Graph/Tree/SubtreesHash.hpp"

#include <algorithm>
#include <limits>
#include <vector>
#include <map>

namespace zawa {

class SubtreesHasher {
public:

    SubtreesHasher() = default;

    template <class G>
    std::vector<usize> operator()(const G& g, usize r = 0u) {
        std::vector<usize> res(g.size());
        auto dfs = [&](auto dfs, usize v, usize p) -> usize {
            std::vector<usize> ch;
            ch.reserve(g[v].size());
            for (usize x : g[v]) if (x != p) {
                ch.push_back(dfs(dfs, x, v));
            }
            std::sort(ch.begin(), ch.end());
            return res[v] = mapping(std::move(ch));
        };
        dfs(dfs, r, std::numeric_limits<u32>::max());
        return res;
    }

private:

    std::map<std::vector<usize>, usize> map;

    usize mapping(std::vector<usize>&& A) {
        usize cur = map.size();
        return map.try_emplace(std::move(A), cur).first->second;
    }
};

} // namespace zawa
#line 4 "Test/LC/rooted_tree_isomorphism_classification.test.cpp"

#line 6 "Test/LC/rooted_tree_isomorphism_classification.test.cpp"
#include <iostream>
#line 8 "Test/LC/rooted_tree_isomorphism_classification.test.cpp"

using namespace zawa;

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);
    int N;
    std::cin >> N;
    std::vector<std::vector<int>> g(N);
    for (int i = 1 ; i < N ; i++) {
        int p;
        std::cin >> p;
        g[p].push_back(i);
    }
    auto ans = SubtreesHasher{}(g);
    auto K = *std::max_element(ans.begin(), ans.end()) + 1;
    std::cout << K << '\n';
    for (int i = 0 ; i < N ; i++) std::cout << ans[i] << (i + 1 == N ? '\n' : ' ');
}
Back to top page