VvyLw's Library

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

View the Project on GitHub

:heavy_check_mark: Manhattan MST
(C++/graph/mst/manhattan.hpp)

Depends on

Verified with

Code

#pragma once

#include <cassert>
#include <map>
#include <numeric>
#include <ranges>
#include "C++/graph/mst/MST.hpp"
namespace man {
template <std::integral T> inline std::vector<edge> manhattan(std::vector<T> x, std::vector<T> y) noexcept {
    assert(std::ssize(x) == std::ssize(y));
    std::vector<edge> ret;
    std::vector<int> id(std::ssize(x));
    std::iota(id.begin(), id.end(), 0);
    for([[maybe_unused]] const auto _: std::views::iota(0, 2)) {
        for([[maybe_unused]] const auto _: std::views::iota(0, 2)) {
            std::ranges::sort(id, [&](const int i, const int j) -> bool { return x[i] + y[i] < x[j] + y[j]; });
            std::map<T, int> idx;
            for(const auto i: id) {
                for(auto it = idx.lower_bound(-y[i]); it != idx.end(); it = idx.erase(it)) {
                    const int j = it->second;
                    if(x[i] - x[j] < y[i] - y[j]) {
                        break;
                    }
                    ret.emplace_back(i, j, -1, std::abs(x[i] - x[j]) + std::abs(y[i] - y[j]));
                }
                idx[-y[i]] = i;
            }
            x.swap(y);
        }
        for(const auto i: std::views::iota(0, std::ssize(x))) {
            x[i] *= -1;
        }
    }
    return ret;
}
}

/**
 * @brief Manhattan MST
 * @see https://ei1333.github.io/library/graph/mst/manhattan-mst.hpp
 */
#line 2 "C++/graph/mst/manhattan.hpp"

#include <cassert>
#include <map>
#include <numeric>
#include <ranges>
#line 2 "C++/graph/mst/MST.hpp"

#include <vector>
#line 2 "C++/graph/edge.hpp"
#ifndef EDGE
#define EDGE
#endif

namespace man {
struct edge {
    int src, to, id;
    long long cost;
    edge(){}
    edge(const int src_, const int to_, const int id_ = -1, const long long cost_ = 0): src(src_), to(to_), id(id_), cost(cost_){}
    constexpr inline operator int() const noexcept { return to; }
};
}

/**
 * @brief Edge
 */
#line 5 "C++/graph/mst/MST.hpp"
struct MST {
    std::vector<man::edge> tree;
    long long cost;
};

/**
 * @brief 最小全域木
 */
#line 8 "C++/graph/mst/manhattan.hpp"
namespace man {
template <std::integral T> inline std::vector<edge> manhattan(std::vector<T> x, std::vector<T> y) noexcept {
    assert(std::ssize(x) == std::ssize(y));
    std::vector<edge> ret;
    std::vector<int> id(std::ssize(x));
    std::iota(id.begin(), id.end(), 0);
    for([[maybe_unused]] const auto _: std::views::iota(0, 2)) {
        for([[maybe_unused]] const auto _: std::views::iota(0, 2)) {
            std::ranges::sort(id, [&](const int i, const int j) -> bool { return x[i] + y[i] < x[j] + y[j]; });
            std::map<T, int> idx;
            for(const auto i: id) {
                for(auto it = idx.lower_bound(-y[i]); it != idx.end(); it = idx.erase(it)) {
                    const int j = it->second;
                    if(x[i] - x[j] < y[i] - y[j]) {
                        break;
                    }
                    ret.emplace_back(i, j, -1, std::abs(x[i] - x[j]) + std::abs(y[i] - y[j]));
                }
                idx[-y[i]] = i;
            }
            x.swap(y);
        }
        for(const auto i: std::views::iota(0, std::ssize(x))) {
            x[i] *= -1;
        }
    }
    return ret;
}
}

/**
 * @brief Manhattan MST
 * @see https://ei1333.github.io/library/graph/mst/manhattan-mst.hpp
 */
Back to top page