ugipro_lib_cpp

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

View the Project on GitHub CURRY-AND-RICE/ugipro_lib_cpp

:warning: tests/graph/minimum_spanning.notest.cpp

Depends on

Code

#include <bits/stdc++.h>
#include "ugilib/graph/minimum_spanning.hpp"

#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/2/GRL_2_A"

using namespace std;

int main() {
    // speed up io
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    // code
    int V, E;
    cin >> V >> E;

    vector<pair<ll, pair<int, int>>> edges;
    for (int i = 0; i < E; i++) {
        int s, t, w;
        cin >> s >> t >> w;
        edges.push_back({w, {s, t}});
    }

    auto [res, mst_edges] = ugilib::kruskal(V, edges);
    cout << res << endl;

    return 0;
}
#line 1 "tests/graph/minimum_spanning.notest.cpp"
#include <bits/stdc++.h>
#line 2 "ugilib/graph/minimum_spanning.hpp"

/**
 * @file minimum_spanning.hpp
 * @brief 最小全域木を求める関数を提供
 *
 * ## 関数一覧
 * - `kruskal(n, edges)` : クラスカル法により最小全域木を求める
*/

#line 3 "ugilib/base/definitions.hpp"

// old (compat)
using ll = long long;
using ull = unsigned long long;
using ld = long double;

// new
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using u128 = __uint128_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;
using i64 = int64_t;
using i128 = __int128_t;
using f32 = float;
using f64 = double;
using f128 = long double;

#define rep(i, n) for(size_t i = 0; i < n; i++)  // rep macro
#define all(v) begin(v), end(v)  // all iterator
#line 4 "ugilib/base/constants.hpp"

namespace ugilib::constants {
    template<typename T>
    inline constexpr T INF = std::numeric_limits<T>::max() / 2;
} // namespace ugilib::constants

const ll INF = ugilib::constants::INF<ll>;
#line 13 "ugilib/graph/minimum_spanning.hpp"
#include <atcoder/dsu>

using namespace std;

namespace ugilib {
    /**
     * @brief クラスカル法により最小全域木を求める
     * @tparam weight_t 辺の重みの型
     * @param n 頂点数
     * @param edges 辺のリスト. ソートするのでコピー渡し
     * @return 最小全域木の重みと含まれる辺のリスト
     * @note 辺のリストは {重み, {頂点1, 頂点2}} の形式で与える
     * @note 辺のリストは重みの昇順にソートされる
     * @note O(E log E). E は辺の数. ボトルネックはソート
    */
    template <typename weight_t>
    tuple<weight_t, vector<pair<int, int>>> kruskal(int n, vector<pair<weight_t, pair<int, int>>> edges) {
        // ソート
        sort(edges.begin(), edges.end());

        // クラスカル法
        // 重みの小さい順に辺を追加していく
        atcoder::dsu uf(n);
        vector<pair<int, int>> mst_edges;
        weight_t res = 0;
        for (auto [w, e] : edges) {
            auto [u, v] = e;
            if (uf.same(u, v)) continue;
            uf.merge(u, v);
            mst_edges.emplace_back(u, v);
            res += w;
            if (uf.size(u) == n) break;
        }

        // 全域木ができなかった場合
        if (uf.size(0) != n) return {-1, {}};
        // 最小全域木の重みと辺のリストを返す
        return {res, mst_edges};
    }
}
#line 3 "tests/graph/minimum_spanning.notest.cpp"

#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/2/GRL_2_A"

using namespace std;

int main() {
    // speed up io
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    // code
    int V, E;
    cin >> V >> E;

    vector<pair<ll, pair<int, int>>> edges;
    for (int i = 0; i < E; i++) {
        int s, t, w;
        cin >> s >> t >> w;
        edges.push_back({w, {s, t}});
    }

    auto [res, mst_edges] = ugilib::kruskal(V, edges);
    cout << res << endl;

    return 0;
}
Back to top page