cp-library

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

View the Project on GitHub rniya/cp-library

:warning: src/util/RandomUndirectedGraphGenarator.hpp

Depends on

Code

#include <iostream>
#include "RandomNumberGenerator.hpp"

template <typename T> struct Edge {
    int u, v;
    T w;
    Edge(int u, int v, T w = 1) : u(u), v(v), w(w) {}
};

template <typename T> struct Graph {
    int n, m;
    std::vector<Edge<T>> es;
    bool weighted;

    Graph(int n, bool weighted = false) : n(n), m(0), weighted(weighted) {}

    void print_as_tree(std::ostream& os, bool origin_zero = false) const {
        os << n << "\n";
        print_edges(os, origin_zero);
    }

    void print(std::ostream& os, bool origin_zero = false) const {
        os << n << " " << m << "\n";
        print_edges(os, origin_zero);
    }

    friend std::ostream& operator<<(std::ostream& os, const Graph& g) {
        g.print_as_tree(os);
        return os;
    }

    void add_edge(int u, int v, T w = 1) {
        assert(0 <= u and u < n);
        assert(0 <= v and v < n);
        es.emplace_back(u, v, w);
        m++;
    }

  private:
    void print_edges(std::ostream& os, bool origin_zero = false) const {
        for (const auto& e : es) {
            os << e.u + (origin_zero ? 0 : 1) << " " << e.v + (origin_zero ? 0 : 1);
            if (weighted) {
                os << " " << e.w;
            }
            os << "\n";
        }
    }
};

template <typename T> struct RandomUndirectedGraphGenerator {
    Graph<T> tree(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        if (n == 2) {
            add_edge(G, 0, 1);
        }
        if (n <= 2) {
            return G;
        }
        std::vector<int> prufer(n - 2), deg(n, 1);
        for (auto& y : prufer) {
            y = rng(n);
            deg[y]++;
        }
        std::set<int> leaves;
        for (int i = 0; i < n; i++) {
            if (deg[i] == 1) {
                leaves.emplace(i);
            }
        }
        for (auto& y : prufer) {
            int x = *leaves.begin();
            add_edge(G, x, y);
            leaves.erase(leaves.begin());
            if (--deg[y] == 1) {
                leaves.emplace(y);
            }
        }
        int u = *leaves.begin(), v = *next(leaves.begin());
        add_edge(G, u, v);
        return G;
    }

    Graph<T> path(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        std::vector<int> ord(n);
        std::iota(ord.begin(), ord.end(), 0);
        rng.shuffle(ord);
        for (int i = 0; i < n - 1; i++) {
            add_edge(G, ord[i], ord[i + 1]);
        }
        return G;
    }

    Graph<T> star(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        int center = rng(n);
        for (int i = 0; i < n; i++) {
            if (i != center) {
                add_edge(G, center, i);
            }
        }
        return G;
    }

    Graph<T> perfect(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                add_edge(G, i, j);
            }
        }
        return G;
    }

    Graph<T> simple(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (rng(2)) {
                    add_edge(G, i, j);
                }
            }
        }
        return G;
    }

  private:
    T w_min, w_max;
    RandomNumberGenerator64 rng;

    void set_weight(bool weighted, T _w_min, T _w_max) {
        assert(0 <= _w_min and _w_min <= _w_max);
        if (weighted) {
            w_min = _w_min;
            w_max = _w_max;
        } else {
            w_min = w_max = 1;
        }
    }

    void add_edge(Graph<T>& G, int u, int v) {
        T w = (w_min == w_max ? w_min : rng(w_min, w_max + 1));
        G.add_edge(u, v, w);
    }
};
#line 1 "src/util/RandomUndirectedGraphGenarator.hpp"
#include <iostream>
#line 2 "src/util/RandomNumberGenerator.hpp"
#include <chrono>
#include <random>
#include <utility>
#include <vector>

struct RandomNumberGenerator {
    std::mt19937 mt;

    RandomNumberGenerator() : mt(std::chrono::steady_clock::now().time_since_epoch().count()) {}

    uint32_t operator()(uint32_t a, uint32_t b) {
        std::uniform_int_distribution<uint32_t> dist(a, b - 1);
        return dist(mt);
    }

    uint32_t operator()(uint32_t b) { return (*this)(0, b); }

    template <typename T> void shuffle(std::vector<T>& v) {
        for (int i = 0; i < int(v.size()); i++) std::swap(v[i], v[(*this)(0, i + 1)]);
    }
};

struct RandomNumberGenerator64 {
    std::mt19937_64 mt;

    RandomNumberGenerator64() : mt(std::chrono::steady_clock::now().time_since_epoch().count()) {}

    uint64_t operator()(uint64_t a, uint64_t b) {
        std::uniform_int_distribution<uint64_t> dist(a, b - 1);
        return dist(mt);
    }

    uint64_t operator()(uint64_t b) { return (*this)(0, b); }

    template <typename T> void shuffle(std::vector<T>& v) {
        for (int i = 0; i < int(v.size()); i++) std::swap(v[i], v[(*this)(0, i + 1)]);
    }
};
#line 3 "src/util/RandomUndirectedGraphGenarator.hpp"

template <typename T> struct Edge {
    int u, v;
    T w;
    Edge(int u, int v, T w = 1) : u(u), v(v), w(w) {}
};

template <typename T> struct Graph {
    int n, m;
    std::vector<Edge<T>> es;
    bool weighted;

    Graph(int n, bool weighted = false) : n(n), m(0), weighted(weighted) {}

    void print_as_tree(std::ostream& os, bool origin_zero = false) const {
        os << n << "\n";
        print_edges(os, origin_zero);
    }

    void print(std::ostream& os, bool origin_zero = false) const {
        os << n << " " << m << "\n";
        print_edges(os, origin_zero);
    }

    friend std::ostream& operator<<(std::ostream& os, const Graph& g) {
        g.print_as_tree(os);
        return os;
    }

    void add_edge(int u, int v, T w = 1) {
        assert(0 <= u and u < n);
        assert(0 <= v and v < n);
        es.emplace_back(u, v, w);
        m++;
    }

  private:
    void print_edges(std::ostream& os, bool origin_zero = false) const {
        for (const auto& e : es) {
            os << e.u + (origin_zero ? 0 : 1) << " " << e.v + (origin_zero ? 0 : 1);
            if (weighted) {
                os << " " << e.w;
            }
            os << "\n";
        }
    }
};

template <typename T> struct RandomUndirectedGraphGenerator {
    Graph<T> tree(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        if (n == 2) {
            add_edge(G, 0, 1);
        }
        if (n <= 2) {
            return G;
        }
        std::vector<int> prufer(n - 2), deg(n, 1);
        for (auto& y : prufer) {
            y = rng(n);
            deg[y]++;
        }
        std::set<int> leaves;
        for (int i = 0; i < n; i++) {
            if (deg[i] == 1) {
                leaves.emplace(i);
            }
        }
        for (auto& y : prufer) {
            int x = *leaves.begin();
            add_edge(G, x, y);
            leaves.erase(leaves.begin());
            if (--deg[y] == 1) {
                leaves.emplace(y);
            }
        }
        int u = *leaves.begin(), v = *next(leaves.begin());
        add_edge(G, u, v);
        return G;
    }

    Graph<T> path(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        std::vector<int> ord(n);
        std::iota(ord.begin(), ord.end(), 0);
        rng.shuffle(ord);
        for (int i = 0; i < n - 1; i++) {
            add_edge(G, ord[i], ord[i + 1]);
        }
        return G;
    }

    Graph<T> star(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        int center = rng(n);
        for (int i = 0; i < n; i++) {
            if (i != center) {
                add_edge(G, center, i);
            }
        }
        return G;
    }

    Graph<T> perfect(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                add_edge(G, i, j);
            }
        }
        return G;
    }

    Graph<T> simple(int n, bool weighted = false, T _w_min = 1, T _w_max = 1) {
        set_weight(weighted, _w_min, _w_max);
        Graph<T> G(n, weighted);
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (rng(2)) {
                    add_edge(G, i, j);
                }
            }
        }
        return G;
    }

  private:
    T w_min, w_max;
    RandomNumberGenerator64 rng;

    void set_weight(bool weighted, T _w_min, T _w_max) {
        assert(0 <= _w_min and _w_min <= _w_max);
        if (weighted) {
            w_min = _w_min;
            w_max = _w_max;
        } else {
            w_min = w_max = 1;
        }
    }

    void add_edge(Graph<T>& G, int u, int v) {
        T w = (w_min == w_max ? w_min : rng(w_min, w_max + 1));
        G.add_edge(u, v, w);
    }
};
Back to top page