QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#102873#6382. LaLa and Spirit SummoninghitonanodeTL 192ms3764kbC++1733.3kb2023-05-03 19:18:292023-05-03 19:18:31

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-03 19:18:31]
  • 评测
  • 测评结果:TL
  • 用时:192ms
  • 内存:3764kb
  • [2023-05-03 19:18:29]
  • 提交

answer

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using lint = long long;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(20); }; } fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template <typename T, typename V>
void ndarray(vector<T>& vec, const V& val, int len) { vec.assign(len, val); }
template <typename T, typename V, typename... Args> void ndarray(vector<T>& vec, const V& val, int len, Args... args) { vec.resize(len), for_each(begin(vec), end(vec), [&](T& v) { ndarray(v, val, args...); }); }
template <typename T> bool chmax(T &m, const T q) { return m < q ? (m = q, true) : false; }
template <typename T> bool chmin(T &m, const T q) { return m > q ? (m = q, true) : false; }
const std::vector<std::pair<int, int>> grid_dxs{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int floor_lg(long long x) { return x <= 0 ? -1 : 63 - __builtin_clzll(x); }
template <class T1, class T2> T1 floor_div(T1 num, T2 den) { return (num > 0 ? num / den : -((-num + den - 1) / den)); }
template <class T1, class T2> std::pair<T1, T2> operator+(const std::pair<T1, T2> &l, const std::pair<T1, T2> &r) { return std::make_pair(l.first + r.first, l.second + r.second); }
template <class T1, class T2> std::pair<T1, T2> operator-(const std::pair<T1, T2> &l, const std::pair<T1, T2> &r) { return std::make_pair(l.first - r.first, l.second - r.second); }
template <class T> std::vector<T> sort_unique(std::vector<T> vec) { sort(vec.begin(), vec.end()), vec.erase(unique(vec.begin(), vec.end()), vec.end()); return vec; }
template <class T> int arglb(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), x)); }
template <class T> int argub(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::upper_bound(v.begin(), v.end(), x)); }
template <class IStream, class T> IStream &operator>>(IStream &is, std::vector<T> &vec) { for (auto &v : vec) is >> v; return is; }

template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);

template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef HITONANODE_LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif

#include <algorithm>
#include <cassert>
#include <vector>

// Directed graph library to find strongly connected components (強連結成分分解)
// 0-indexed directed graph
// Complexity: O(V + E)
struct DirectedGraphSCC {
    int V; // # of Vertices
    std::vector<std::vector<int>> to, from;
    std::vector<int> used; // Only true/false
    std::vector<int> vs;
    std::vector<int> cmp;
    int scc_num = -1;

    DirectedGraphSCC(int V = 0) : V(V), to(V), from(V), cmp(V) {}

    void _dfs(int v) {
        used[v] = true;
        for (auto t : to[v])
            if (!used[t]) _dfs(t);
        vs.push_back(v);
    }
    void _rdfs(int v, int k) {
        used[v] = true;
        cmp[v] = k;
        for (auto t : from[v])
            if (!used[t]) _rdfs(t, k);
    }

    void add_edge(int from_, int to_) {
        assert(from_ >= 0 and from_ < V and to_ >= 0 and to_ < V);
        to[from_].push_back(to_);
        from[to_].push_back(from_);
    }

    // Detect strongly connected components and return # of them.
    // Also, assign each vertex `v` the scc id `cmp[v]` (0-indexed)
    int FindStronglyConnectedComponents() {
        used.assign(V, false);
        vs.clear();
        for (int v = 0; v < V; v++)
            if (!used[v]) _dfs(v);
        used.assign(V, false);
        scc_num = 0;
        for (int i = (int)vs.size() - 1; i >= 0; i--)
            if (!used[vs[i]]) _rdfs(vs[i], scc_num++);
        return scc_num;
    }

    // Find and output the vertices that form a closed cycle.
    // output: {v_1, ..., v_C}, where C is the length of cycle,
    //         {} if there's NO cycle (graph is DAG)
    int _c, _init;
    std::vector<int> _ret_cycle;
    bool _dfs_detectcycle(int now, bool b0) {
        if (now == _init and b0) return true;
        for (auto nxt : to[now])
            if (cmp[nxt] == _c and !used[nxt]) {
                _ret_cycle.emplace_back(nxt), used[nxt] = 1;
                if (_dfs_detectcycle(nxt, true)) return true;
                _ret_cycle.pop_back();
            }
        return false;
    }
    std::vector<int> DetectCycle() {
        int ns = FindStronglyConnectedComponents();
        if (ns == V) return {};
        std::vector<int> cnt(ns);
        for (auto x : cmp) cnt[x]++;
        _c = std::find_if(cnt.begin(), cnt.end(), [](int x) { return x > 1; }) - cnt.begin();
        _init = std::find(cmp.begin(), cmp.end(), _c) - cmp.begin();
        used.assign(V, false);
        _ret_cycle.clear();
        _dfs_detectcycle(_init, false);
        return _ret_cycle;
    }

    // After calling `FindStronglyConnectedComponents()`, generate a new graph by uniting all
    // vertices belonging to the same component(The resultant graph is DAG).
    DirectedGraphSCC GenerateTopologicalGraph() {
        DirectedGraphSCC newgraph(scc_num);
        for (int s = 0; s < V; s++)
            for (auto t : to[s]) {
                if (cmp[s] != cmp[t]) newgraph.add_edge(cmp[s], cmp[t]);
            }
        return newgraph;
    }
};

#include <cassert>
#include <iostream>
#include <vector>

// Bipartite matching of undirected bipartite graph (Hopcroft-Karp)
// https://ei1333.github.io/luzhiled/snippets/graph/hopcroft-karp.html
// Comprexity: O((V + E)sqrtV)
// int solve(): enumerate maximum number of matching / return -1 (if graph is not bipartite)
struct BipartiteMatching {
    int V;
    std::vector<std::vector<int>> to; // Adjacency list
    std::vector<int> dist;            // dist[i] = (Distance from i'th node)
    std::vector<int> match;           // match[i] = (Partner of i'th node) or -1 (No parter)
    std::vector<int> used, vv;
    std::vector<int> color; // color of each node(checking bipartition): 0/1/-1(not determined)

    BipartiteMatching() = default;
    BipartiteMatching(int V_) : V(V_), to(V_), match(V_, -1), used(V_), color(V_, -1) {}

    void add_edge(int u, int v) {
        assert(u >= 0 and u < V and v >= 0 and v < V and u != v);
        to[u].push_back(v);
        to[v].push_back(u);
    }

    void _bfs() {
        dist.assign(V, -1);
        std::vector<int> q;
        int lq = 0;
        for (int i = 0; i < V; i++) {
            if (!color[i] and !used[i]) q.push_back(i), dist[i] = 0;
        }

        while (lq < int(q.size())) {
            int now = q[lq++];
            for (auto nxt : to[now]) {
                int c = match[nxt];
                if (c >= 0 and dist[c] == -1) q.push_back(c), dist[c] = dist[now] + 1;
            }
        }
    }

    bool _dfs(int now) {
        vv[now] = true;
        for (auto nxt : to[now]) {
            int c = match[nxt];
            if (c < 0 or (!vv[c] and dist[c] == dist[now] + 1 and _dfs(c))) {
                match[nxt] = now, match[now] = nxt;
                used[now] = true;
                return true;
            }
        }
        return false;
    }

    bool _color_bfs(int root) {
        color[root] = 0;
        std::vector<int> q{root};
        int lq = 0;
        while (lq < int(q.size())) {
            int now = q[lq++], c = color[now];
            for (auto nxt : to[now]) {
                if (color[nxt] == -1) {
                    color[nxt] = !c, q.push_back(nxt);
                } else if (color[nxt] == c) {
                    return false;
                }
            }
        }
        return true;
    }

    int solve() {
        for (int i = 0; i < V; i++) {
            if (color[i] == -1 and !_color_bfs(i)) return -1;
        }
        int ret = 0;
        while (true) {
            _bfs();
            vv.assign(V, false);
            int flow = 0;
            for (int i = 0; i < V; i++) {
                if (!color[i] and !used[i] and _dfs(i)) flow++;
            }
            if (!flow) break;
            ret += flow;
        }
        return ret;
    }

    template <class OStream> friend OStream &operator<<(OStream &os, const BipartiteMatching &bm) {
        os << "{N=" << bm.V << ':';
        for (int i = 0; i < bm.V; i++) {
            if (bm.match[i] > i) os << '(' << i << '-' << bm.match[i] << "),";
        }
        return os << '}';
    }
};


// Dulmage–Mendelsohn (DM) decomposition (DM 分解)
// return: [(W+0, W-0), (W+1,W-1),...,(W+(k+1), W-(k+1))]
//         : sequence of pair (left vetrices, right vertices)
//         - |W+0| < |W-0| or both empty
//         - |W+i| = |W-i| (i = 1, ..., k)
//         - |W+(k+1)| > |W-(k+1)| or both empty
//         - W is topologically sorted
// Example:
// (2, 2, [(0,0), (0,1), (1,0)]) => [([],[]),([0,],[1,]),([1,],[0,]),([],[]),]
// Complexity: O(N + (N + M) sqrt(N))
// Verified: https://yukicoder.me/problems/no/1615
std::vector<std::pair<std::vector<int>, std::vector<int>>>
dulmage_mendelsohn(int L, int R, const std::vector<std::pair<int, int>> &edges) {
    for (auto p : edges) {
        assert(0 <= p.first and p.first < L);
        assert(0 <= p.second and p.second < R);
    }

    BipartiteMatching bm(L + R);
    for (auto p : edges) bm.add_edge(p.first, L + p.second);
    bm.solve();

    DirectedGraphSCC scc(L + R);
    for (auto p : edges) scc.add_edge(p.first, L + p.second);
    for (int l = 0; l < L; ++l) {
        if (bm.match[l] >= L) scc.add_edge(bm.match[l], l);
    }

    int nscc = scc.FindStronglyConnectedComponents();
    std::vector<int> cmp_map(nscc, -2);

    std::vector<int> vis(L + R);
    std::vector<int> st;
    for (int c = 0; c < 2; ++c) {
        std::vector<std::vector<int>> to(L + R);
        auto color = [&L](int x) { return x >= L; };
        for (auto p : edges) {
            int u = p.first, v = L + p.second;
            if (color(u) != c) std::swap(u, v);
            to[u].push_back(v);
            if (bm.match[u] == v) to[v].push_back(u);
        }
        for (int i = 0; i < L + R; ++i) {
            if (bm.match[i] >= 0 or color(i) != c or vis[i]) continue;
            vis[i] = 1, st = {i};
            while (!st.empty()) {
                int now = st.back();
                cmp_map[scc.cmp[now]] = c - 1;
                st.pop_back();
                for (int nxt : to[now]) {
                    if (!vis[nxt]) vis[nxt] = 1, st.push_back(nxt);
                }
            }
        }
    }

    int nset = 1;
    for (int n = 0; n < nscc; ++n) {
        if (cmp_map[n] == -2) cmp_map[n] = nset++;
    }
    for (auto &x : cmp_map) {
        if (x == -1) x = nset;
    }
    nset++;

    std::vector<std::pair<std::vector<int>, std::vector<int>>> groups(nset);

    for (int l = 0; l < L; ++l) {
        if (bm.match[l] < 0) continue;
        int c = cmp_map[scc.cmp[l]];
        groups[c].first.push_back(l);
        groups[c].second.push_back(bm.match[l] - L);
    }
    for (int l = 0; l < L; ++l) {
        if (bm.match[l] >= 0) continue;
        int c = cmp_map[scc.cmp[l]];
        groups[c].first.push_back(l);
    }
    for (int r = 0; r < R; ++r) {
        if (bm.match[L + r] >= 0) continue;
        int c = cmp_map[scc.cmp[L + r]];
        groups[c].second.push_back(r);
    }

    return groups;
}


#include <algorithm>
#include <cassert>
#include <deque>
#include <fstream>
#include <functional>
#include <limits>
#include <queue>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

template <typename T, T INF = std::numeric_limits<T>::max() / 2, int INVALID = -1>
struct shortest_path {
    int V, E;
    bool single_positive_weight;
    T wmin, wmax;

    std::vector<std::pair<int, T>> tos;
    std::vector<int> head;
    std::vector<std::tuple<int, int, T>> edges;

    void build_() {
        if (int(tos.size()) == E and int(head.size()) == V + 1) return;
        tos.resize(E);
        head.assign(V + 1, 0);
        for (const auto &e : edges) ++head[std::get<0>(e) + 1];
        for (int i = 0; i < V; ++i) head[i + 1] += head[i];
        auto cur = head;
        for (const auto &e : edges) {
            tos[cur[std::get<0>(e)]++] = std::make_pair(std::get<1>(e), std::get<2>(e));
        }
    }

    shortest_path(int V = 0) : V(V), E(0), single_positive_weight(true), wmin(0), wmax(0) {}
    void add_edge(int s, int t, T w) {
        assert(0 <= s and s < V);
        assert(0 <= t and t < V);
        edges.emplace_back(s, t, w);
        ++E;
        if (w > 0 and wmax > 0 and wmax != w) single_positive_weight = false;
        wmin = std::min(wmin, w);
        wmax = std::max(wmax, w);
    }

    void add_bi_edge(int u, int v, T w) {
        add_edge(u, v, w);
        add_edge(v, u, w);
    }

    std::vector<T> dist;
    std::vector<int> prev;

    // Dijkstra algorithm
    // - Requirement: wmin >= 0
    // - Complexity: O(E log E)
    using Pque = std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>,
                                     std::greater<std::pair<T, int>>>;
    template <class Heap = Pque> void dijkstra(int s, int t = INVALID) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF);
        prev.assign(V, INVALID);
        dist[s] = 0;
        Heap pq;
        pq.emplace(0, s);
        while (!pq.empty()) {
            T d;
            int v;
            std::tie(d, v) = pq.top();
            pq.pop();
            if (t == v) return;
            if (dist[v] < d) continue;
            for (int e = head[v]; e < head[v + 1]; ++e) {
                const auto &nx = tos[e];
                T dnx = d + nx.second;
                if (dist[nx.first] > dnx) {
                    dist[nx.first] = dnx, prev[nx.first] = v;
                    pq.emplace(dnx, nx.first);
                }
            }
        }
    }

    // Dijkstra algorithm
    // - Requirement: wmin >= 0
    // - Complexity: O(V^2 + E)
    void dijkstra_vquad(int s, int t = INVALID) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF);
        prev.assign(V, INVALID);
        dist[s] = 0;
        std::vector<char> fixed(V, false);
        while (true) {
            int r = INVALID;
            T dr = INF;
            for (int i = 0; i < V; i++) {
                if (!fixed[i] and dist[i] < dr) r = i, dr = dist[i];
            }
            if (r == INVALID or r == t) break;
            fixed[r] = true;
            int nxt;
            T dx;
            for (int e = head[r]; e < head[r + 1]; ++e) {
                std::tie(nxt, dx) = tos[e];
                if (dist[nxt] > dist[r] + dx) dist[nxt] = dist[r] + dx, prev[nxt] = r;
            }
        }
    }

    // Bellman-Ford algorithm
    // - Requirement: no negative loop
    // - Complexity: O(VE)
    bool bellman_ford(int s, int nb_loop) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF), prev.assign(V, INVALID);
        dist[s] = 0;
        for (int l = 0; l < nb_loop; l++) {
            bool upd = false;
            for (int v = 0; v < V; v++) {
                if (dist[v] == INF) continue;
                for (int e = head[v]; e < head[v + 1]; ++e) {
                    const auto &nx = tos[e];
                    T dnx = dist[v] + nx.second;
                    if (dist[nx.first] > dnx) dist[nx.first] = dnx, prev[nx.first] = v, upd = true;
                }
            }
            if (!upd) return true;
        }
        return false;
    }

    // Bellman-ford algorithm using deque
    // - Requirement: no negative loop
    // - Complexity: O(VE)
    void spfa(int s) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF);
        prev.assign(V, INVALID);
        dist[s] = 0;
        std::deque<int> q;
        std::vector<char> in_queue(V);
        q.push_back(s), in_queue[s] = 1;
        while (!q.empty()) {
            int now = q.front();
            q.pop_front(), in_queue[now] = 0;
            for (int e = head[now]; e < head[now + 1]; ++e) {
                const auto &nx = tos[e];
                T dnx = dist[now] + nx.second;
                int nxt = nx.first;
                if (dist[nxt] > dnx) {
                    dist[nxt] = dnx;
                    if (!in_queue[nxt]) {
                        if (q.size() and dnx < dist[q.front()]) { // Small label first optimization
                            q.push_front(nxt);
                        } else {
                            q.push_back(nxt);
                        }
                        prev[nxt] = now, in_queue[nxt] = 1;
                    }
                }
            }
        }
    }

    // 01-BFS
    // - Requirement: all weights must be 0 or w (positive constant).
    // - Complexity: O(V + E)
    void zero_one_bfs(int s, int t = INVALID) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF), prev.assign(V, INVALID);
        dist[s] = 0;
        std::vector<int> q(V * 4);
        int ql = V * 2, qr = V * 2;
        q[qr++] = s;
        while (ql < qr) {
            int v = q[ql++];
            if (v == t) return;
            for (int e = head[v]; e < head[v + 1]; ++e) {
                const auto &nx = tos[e];
                T dnx = dist[v] + nx.second;
                if (dist[nx.first] > dnx) {
                    dist[nx.first] = dnx, prev[nx.first] = v;
                    if (nx.second) {
                        q[qr++] = nx.first;
                    } else {
                        q[--ql] = nx.first;
                    }
                }
            }
        }
    }

    // Dial's algorithm
    // - Requirement: wmin >= 0
    // - Complexity: O(wmax * V + E)
    void dial(int s, int t = INVALID) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF), prev.assign(V, INVALID);
        dist[s] = 0;
        std::vector<std::vector<std::pair<int, T>>> q(wmax + 1);
        q[0].emplace_back(s, dist[s]);
        int ninq = 1;

        int cur = 0;
        T dcur = 0;
        for (; ninq; ++cur, ++dcur) {
            if (cur == wmax + 1) cur = 0;
            while (!q[cur].empty()) {
                int v = q[cur].back().first;
                T dnow = q[cur].back().second;
                q[cur].pop_back(), --ninq;
                if (v == t) return;
                if (dist[v] < dnow) continue;

                for (int e = head[v]; e < head[v + 1]; ++e) {
                    const auto &nx = tos[e];
                    T dnx = dist[v] + nx.second;
                    if (dist[nx.first] > dnx) {
                        dist[nx.first] = dnx, prev[nx.first] = v;
                        int nxtcur = cur + int(nx.second);
                        if (nxtcur >= int(q.size())) nxtcur -= q.size();
                        q[nxtcur].emplace_back(nx.first, dnx), ++ninq;
                    }
                }
            }
        }
    }

    // Solver for DAG
    // - Requirement: graph is DAG
    // - Complexity: O(V + E)
    bool dag_solver(int s) {
        assert(0 <= s and s < V);
        build_();
        dist.assign(V, INF), prev.assign(V, INVALID);
        dist[s] = 0;
        std::vector<int> indeg(V, 0);
        std::vector<int> q(V * 2);
        int ql = 0, qr = 0;
        q[qr++] = s;
        while (ql < qr) {
            int now = q[ql++];
            for (int e = head[now]; e < head[now + 1]; ++e) {
                const auto &nx = tos[e];
                ++indeg[nx.first];
                if (indeg[nx.first] == 1) q[qr++] = nx.first;
            }
        }
        ql = qr = 0;
        q[qr++] = s;
        while (ql < qr) {
            int now = q[ql++];
            for (int e = head[now]; e < head[now + 1]; ++e) {
                const auto &nx = tos[e];
                --indeg[nx.first];
                if (dist[nx.first] > dist[now] + nx.second)
                    dist[nx.first] = dist[now] + nx.second, prev[nx.first] = now;
                if (indeg[nx.first] == 0) q[qr++] = nx.first;
            }
        }
        return *max_element(indeg.begin(), indeg.end()) == 0;
    }

    // Retrieve a sequence of vertex ids that represents shortest path [s, ..., goal]
    // If not reachable to goal, return {}
    std::vector<int> retrieve_path(int goal) const {
        assert(int(prev.size()) == V);
        assert(0 <= goal and goal < V);
        if (dist[goal] == INF) return {};
        std::vector<int> ret{goal};
        while (prev[goal] != INVALID) {
            goal = prev[goal];
            ret.push_back(goal);
        }
        std::reverse(ret.begin(), ret.end());
        return ret;
    }

    void solve(int s, int t = INVALID) {
        if (wmin >= 0) {
            if (single_positive_weight) {
                zero_one_bfs(s, t);
            } else if (wmax <= 10) {
                dial(s, t);
            } else {
                if ((long long)V * V < (E << 4)) {
                    dijkstra_vquad(s, t);
                } else {
                    dijkstra(s, t);
                }
            }
        } else {
            bellman_ford(s, V);
        }
    }

    // Warshall-Floyd algorithm
    // - Requirement: no negative loop
    // - Complexity: O(E + V^3)
    std::vector<std::vector<T>> floyd_warshall() {
        build_();
        std::vector<std::vector<T>> dist2d(V, std::vector<T>(V, INF));
        for (int i = 0; i < V; i++) {
            dist2d[i][i] = 0;
            for (const auto &e : edges) {
                int s = std::get<0>(e), t = std::get<1>(e);
                dist2d[s][t] = std::min(dist2d[s][t], std::get<2>(e));
            }
        }
        for (int k = 0; k < V; k++) {
            for (int i = 0; i < V; i++) {
                if (dist2d[i][k] == INF) continue;
                for (int j = 0; j < V; j++) {
                    if (dist2d[k][j] == INF) continue;
                    dist2d[i][j] = std::min(dist2d[i][j], dist2d[i][k] + dist2d[k][j]);
                }
            }
        }
        return dist2d;
    }

    void to_dot(std::string filename = "shortest_path") const {
        std::ofstream ss(filename + ".DOT");
        ss << "digraph{\n";
        build_();
        for (int i = 0; i < V; i++) {
            for (int e = head[i]; e < head[i + 1]; ++e) {
                ss << i << "->" << tos[e].first << "[label=" << tos[e].second << "];\n";
            }
        }
        ss << "}\n";
        ss.close();
        return;
    }
};


#include <cassert>
#include <vector>

// Partition matroid (partitional matroid) : direct sum of uniform matroids
class PartitionMatroid {
    using Element = int;
    int M;
    std::vector<std::vector<Element>> parts;
    std::vector<int> belong;
    std::vector<int> R;
    std::vector<int> cnt;
    std::vector<std::vector<Element>> circuits;

public:
    // parts: partition of [0, 1, ..., M - 1]
    // R: only R[i] elements from parts[i] can be chosen for each i.
    PartitionMatroid(int M, const std::vector<std::vector<int>> &parts_, const std::vector<int> &R_)
        : M(M), parts(parts_), belong(M, -1), R(R_) {
        assert(parts.size() == R.size());
        for (int i = 0; i < int(parts.size()); i++) {
            for (Element e : parts[i]) belong[e] = i;
        }
        for (Element e = 0; e < M; e++) {
            // assert(belong[e] != -1);
            if (belong[e] == -1) {
                belong[e] = parts.size();
                parts.push_back({e});
                R.push_back(1);
            }
        }
    }
    int size() const { return M; }

    template <class State> void set(const State &I) {
        cnt = R;
        for (int e = 0; e < M; e++) {
            if (I[e]) cnt[belong[e]]--;
        }
        circuits.assign(cnt.size(), {});
        for (int e = 0; e < M; e++) {
            if (I[e] and cnt[belong[e]] == 0) circuits[belong[e]].push_back(e);
        }
    }

    std::vector<Element> circuit(const Element e) const {
        assert(0 <= e and e < M);
        int p = belong[e];
        if (cnt[p] == 0) {
            auto ret = circuits[p];
            ret.push_back(e);
            return ret;
        }
        return {};
    }
};



// (Min weight) matroid intersection solver
// Algorithm based on http://dopal.cs.uec.ac.jp/okamotoy/lect/2015/matroid/
// Complexity: O(CE^2 + E^3) (C : circuit query, non-weighted)
template <class M1, class M2, class T = int>
std::vector<bool> MatroidIntersection(M1 matroid1, M2 matroid2, std::vector<bool> I) {
    using State = std::vector<bool>;
    using Element = int;
    assert(matroid1.size() == matroid2.size());
    const int M = matroid1.size();

    const Element gs = M, gt = M + 1;
    // State I(M);

    while (true) {
        shortest_path<T> sssp(M + 2);
        matroid1.set(I);
        matroid2.set(I);
        for (int e = 0; e < M; e++) {
            if (I[e]) continue;
            auto c1 = matroid1.circuit(e), c2 = matroid2.circuit(e);
            if (c1.empty()) sssp.add_edge(e, gt, 0);
            for (Element f : c1) {
                if (f != e) sssp.add_edge(e, f, 1);
            }
            if (c2.empty()) sssp.add_edge(gs, e, 1);
            for (Element f : c2) {
                if (f != e) sssp.add_edge(f, e, 1);
            }
        }
        sssp.solve(gs, gt);
        auto aug_path = sssp.retrieve_path(gt);
        if (aug_path.empty()) break;
        for (auto e : aug_path) {
            if (e != gs and e != gt) I[e] = !I[e];
        }
    }
    return I;
}


int N, M;
vector<pint> edges;
vector<vector<int>> to;


struct RigidityMatroid {
    using Element = int;

    // vector<bool> I;
    vector<int> eids;

    int size() { return M; }; // # of elements of set we consider

    template <class State = std::vector<bool>> void set(State I_) {
        eids.clear();
        for (int e = 0; e < size(); ++e) {
            if (I_[e]) eids.push_back(e);
        }
    }

    std::vector<Element> circuit(const Element &e) const {
        std::vector<pair<int, int>> dm_edges;
        const int u0 = edges.at(e).first, u1 = edges.at(e).second;

        for (int i = 0; i < eids.size(); ++i) {
            const int e = eids.at(i);
            for (int v : {edges.at(e).first, edges.at(e).second}) {
                if (v == u0 or v == u1) continue;
                for (int d = 0; d < 2; ++d) dm_edges.emplace_back(i, v * 2 + d);
            }
        }

        auto dm = dulmage_mendelsohn(eids.size(), N * 2, dm_edges).back();

        std::vector<Element> ret;
        for (int i : dm.first) ret.push_back(eids.at(i));
        return ret;
    }
};



#include <algorithm>
#include <numeric>
#include <utility>
#include <vector>

// UnionFind Tree (0-indexed), based on size of each disjoint set
struct UnionFind {
    std::vector<int> par, cou;
    UnionFind(int N = 0) : par(N), cou(N, 1) { iota(par.begin(), par.end(), 0); }
    int find(int x) { return (par[x] == x) ? x : (par[x] = find(par[x])); }
    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return false;
        if (cou[x] < cou[y]) std::swap(x, y);
        par[y] = x, cou[x] += cou[y];
        return true;
    }
    int count(int x) { return cou[find(x)]; }
    bool same(int x, int y) { return find(x) == find(y); }
    std::vector<std::vector<int>> groups() {
        std::vector<std::vector<int>> ret(par.size());
        for (int i = 0; i < int(par.size()); ++i) ret[find(i)].push_back(i);
        ret.erase(std::remove_if(ret.begin(), ret.end(),
                                 [&](const std::vector<int> &v) { return v.empty(); }),
                  ret.end());
        return ret;
    }
};


int main() {
    cin >> N >> M;
    to.resize(N);
    vector<vector<int>> color2e(M);
    vector<int> color(M);
    vector<int> lim(M, 1);
    REP(e, M) {
        int u, v, c;
        cin >> u >> v >> c;
        to.at(u).push_back(v);
        to.at(v).push_back(u);
        color.at(e) = c;
        edges.emplace_back(u, v);
        color2e.at(c).push_back(e);
    }
    vector<bool> I(M);
    vector<bitset<200>> conn(N);
    REP(i, N) conn.at(i).set(i);
    vector<int> used_color(M);

    RigidityMatroid rm;
    REP(e, M) {
        auto [a, b] = edges.at(e);
        if (used_color.at(color.at(e))) continue;
        if ((conn[a] & conn[b]).any()) continue;

        rm.set(I);
        if (rm.circuit(e).empty()) {
            I[e] = 1;
            conn[a][b] = conn[b][a] = 1;
            used_color.at(color.at(e)) = 1;
        }
    }

    PartitionMatroid matroid2(M, color2e, lim);

    RigidityMatroid mat;

    auto sol = MatroidIntersection(mat, matroid2, I);
    dbg(sol);
    cout << N * 2 - accumulate(ALL(sol), 0) << endl;
}

詳細信息

Test #1:

score: 100
Accepted
time: 2ms
memory: 3452kb

input:

3 3
0 1 0
0 2 0
1 2 0

output:

5

result:

ok 1 number(s): "5"

Test #2:

score: 0
Accepted
time: 2ms
memory: 3456kb

input:

3 3
0 1 0
0 2 1
1 2 2

output:

3

result:

ok 1 number(s): "3"

Test #3:

score: 0
Accepted
time: 2ms
memory: 3492kb

input:

4 4
0 1 0
1 2 1
2 3 2
0 3 3

output:

4

result:

ok 1 number(s): "4"

Test #4:

score: 0
Accepted
time: 2ms
memory: 3480kb

input:

5 4
0 1 0
1 2 1
2 3 2
3 4 3

output:

6

result:

ok 1 number(s): "6"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3484kb

input:

2 0

output:

4

result:

ok 1 number(s): "4"

Test #6:

score: 0
Accepted
time: 2ms
memory: 3492kb

input:

2 1
0 1 0

output:

3

result:

ok 1 number(s): "3"

Test #7:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

2 2
0 1 0
0 1 1

output:

3

result:

ok 1 number(s): "3"

Test #8:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

2 3
0 1 0
0 1 2
0 1 0

output:

3

result:

ok 1 number(s): "3"

Test #9:

score: 0
Accepted
time: 1ms
memory: 3424kb

input:

2 4
0 1 2
0 1 3
0 1 2
0 1 3

output:

3

result:

ok 1 number(s): "3"

Test #10:

score: 0
Accepted
time: 2ms
memory: 3472kb

input:

2 5
0 1 2
0 1 4
0 1 3
0 1 4
0 1 3

output:

3

result:

ok 1 number(s): "3"

Test #11:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

2 6
0 1 3
0 1 3
0 1 1
0 1 0
0 1 3
0 1 4

output:

3

result:

ok 1 number(s): "3"

Test #12:

score: 0
Accepted
time: 0ms
memory: 3428kb

input:

2 7
0 1 1
0 1 5
0 1 6
0 1 4
0 1 1
0 1 2
0 1 3

output:

3

result:

ok 1 number(s): "3"

Test #13:

score: 0
Accepted
time: 0ms
memory: 3428kb

input:

2 8
0 1 2
0 1 5
0 1 1
0 1 4
0 1 2
0 1 1
0 1 1
0 1 1

output:

3

result:

ok 1 number(s): "3"

Test #14:

score: 0
Accepted
time: 0ms
memory: 3420kb

input:

2 9
0 1 8
0 1 7
0 1 0
0 1 7
0 1 4
0 1 1
0 1 2
0 1 8
0 1 5

output:

3

result:

ok 1 number(s): "3"

Test #15:

score: 0
Accepted
time: 2ms
memory: 3452kb

input:

2 10
0 1 0
0 1 7
0 1 8
0 1 5
0 1 8
0 1 7
0 1 8
0 1 3
0 1 4
0 1 3

output:

3

result:

ok 1 number(s): "3"

Test #16:

score: 0
Accepted
time: 2ms
memory: 3404kb

input:

3 0

output:

6

result:

ok 1 number(s): "6"

Test #17:

score: 0
Accepted
time: 2ms
memory: 3412kb

input:

3 1
1 2 0

output:

5

result:

ok 1 number(s): "5"

Test #18:

score: 0
Accepted
time: 1ms
memory: 3408kb

input:

3 2
1 2 1
1 2 1

output:

5

result:

ok 1 number(s): "5"

Test #19:

score: 0
Accepted
time: 0ms
memory: 3488kb

input:

3 3
1 2 2
1 2 1
0 1 1

output:

4

result:

ok 1 number(s): "4"

Test #20:

score: 0
Accepted
time: 2ms
memory: 3448kb

input:

3 4
1 2 3
0 2 1
1 2 0
1 2 3

output:

4

result:

ok 1 number(s): "4"

Test #21:

score: 0
Accepted
time: 2ms
memory: 3456kb

input:

3 5
1 2 0
1 2 2
0 1 4
0 2 0
0 1 0

output:

3

result:

ok 1 number(s): "3"

Test #22:

score: 0
Accepted
time: 2ms
memory: 3524kb

input:

3 6
1 2 4
0 1 1
0 2 5
1 2 1
0 2 3
0 1 4

output:

3

result:

ok 1 number(s): "3"

Test #23:

score: 0
Accepted
time: 2ms
memory: 3428kb

input:

3 7
1 2 6
1 2 2
1 2 4
1 2 6
1 2 1
0 2 2
0 1 6

output:

3

result:

ok 1 number(s): "3"

Test #24:

score: 0
Accepted
time: 2ms
memory: 3400kb

input:

3 8
1 2 6
0 1 2
0 1 4
0 2 3
1 2 1
1 2 0
0 2 4
1 2 4

output:

3

result:

ok 1 number(s): "3"

Test #25:

score: 0
Accepted
time: 2ms
memory: 3464kb

input:

3 9
1 2 8
1 2 4
1 2 4
1 2 8
1 2 8
1 2 4
1 2 7
0 1 3
0 2 2

output:

3

result:

ok 1 number(s): "3"

Test #26:

score: 0
Accepted
time: 2ms
memory: 3464kb

input:

3 10
0 1 9
0 2 4
0 1 0
0 1 9
1 2 4
0 1 9
1 2 9
1 2 5
1 2 5
0 1 0

output:

3

result:

ok 1 number(s): "3"

Test #27:

score: 0
Accepted
time: 0ms
memory: 3452kb

input:

4 0

output:

8

result:

ok 1 number(s): "8"

Test #28:

score: 0
Accepted
time: 2ms
memory: 3496kb

input:

4 1
1 3 0

output:

7

result:

ok 1 number(s): "7"

Test #29:

score: 0
Accepted
time: 2ms
memory: 3408kb

input:

4 2
0 1 0
1 2 0

output:

7

result:

ok 1 number(s): "7"

Test #30:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

4 3
0 3 0
2 3 1
0 3 1

output:

6

result:

ok 1 number(s): "6"

Test #31:

score: 0
Accepted
time: 2ms
memory: 3392kb

input:

4 4
2 3 1
2 3 0
0 2 2
0 1 2

output:

6

result:

ok 1 number(s): "6"

Test #32:

score: 0
Accepted
time: 2ms
memory: 3496kb

input:

4 5
2 3 1
0 1 2
1 3 3
0 3 2
2 3 3

output:

5

result:

ok 1 number(s): "5"

Test #33:

score: 0
Accepted
time: 1ms
memory: 3464kb

input:

4 6
1 3 1
0 2 5
0 3 0
0 2 3
1 3 2
0 3 4

output:

5

result:

ok 1 number(s): "5"

Test #34:

score: 0
Accepted
time: 0ms
memory: 3472kb

input:

4 7
1 2 4
0 3 4
0 2 1
2 3 4
0 2 0
0 1 1
1 3 3

output:

4

result:

ok 1 number(s): "4"

Test #35:

score: 0
Accepted
time: 0ms
memory: 3420kb

input:

4 8
0 2 1
0 3 7
1 3 7
2 3 3
1 2 0
2 3 7
1 2 0
2 3 0

output:

4

result:

ok 1 number(s): "4"

Test #36:

score: 0
Accepted
time: 1ms
memory: 3424kb

input:

4 9
0 2 5
0 3 0
1 2 5
0 2 1
2 3 1
1 3 7
1 3 2
2 3 5
0 2 8

output:

3

result:

ok 1 number(s): "3"

Test #37:

score: 0
Accepted
time: 0ms
memory: 3524kb

input:

4 10
1 2 0
0 2 0
2 3 0
0 1 1
2 3 8
1 2 2
0 3 9
1 3 6
1 2 6
1 2 4

output:

3

result:

ok 1 number(s): "3"

Test #38:

score: 0
Accepted
time: 2ms
memory: 3420kb

input:

5 0

output:

10

result:

ok 1 number(s): "10"

Test #39:

score: 0
Accepted
time: 2ms
memory: 3428kb

input:

5 1
0 4 0

output:

9

result:

ok 1 number(s): "9"

Test #40:

score: 0
Accepted
time: 2ms
memory: 3432kb

input:

5 2
0 3 0
0 3 1

output:

9

result:

ok 1 number(s): "9"

Test #41:

score: 0
Accepted
time: 2ms
memory: 3496kb

input:

5 3
0 2 0
1 4 2
1 2 2

output:

8

result:

ok 1 number(s): "8"

Test #42:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

5 4
0 1 3
3 4 2
3 4 3
2 3 2

output:

8

result:

ok 1 number(s): "8"

Test #43:

score: 0
Accepted
time: 2ms
memory: 3428kb

input:

5 5
0 3 4
1 2 3
2 4 0
0 4 4
1 4 3

output:

7

result:

ok 1 number(s): "7"

Test #44:

score: 0
Accepted
time: 1ms
memory: 3420kb

input:

5 6
0 2 2
3 4 5
0 3 4
1 2 5
1 2 1
3 4 4

output:

6

result:

ok 1 number(s): "6"

Test #45:

score: 0
Accepted
time: 0ms
memory: 3528kb

input:

5 7
0 1 0
0 2 6
3 4 3
3 4 0
0 2 6
3 4 6
3 4 4

output:

7

result:

ok 1 number(s): "7"

Test #46:

score: 0
Accepted
time: 2ms
memory: 3464kb

input:

5 8
0 4 5
2 4 4
1 2 3
1 4 2
0 3 7
2 3 6
3 4 3
3 4 4

output:

4

result:

ok 1 number(s): "4"

Test #47:

score: 0
Accepted
time: 2ms
memory: 3524kb

input:

5 9
0 2 5
0 2 4
0 2 8
2 4 3
0 1 3
2 4 3
2 3 8
0 3 8
3 4 4

output:

6

result:

ok 1 number(s): "6"

Test #48:

score: 0
Accepted
time: 1ms
memory: 3424kb

input:

5 10
0 2 9
3 4 7
0 3 9
0 2 3
2 4 4
3 4 3
2 3 1
0 1 9
3 4 9
2 3 8

output:

5

result:

ok 1 number(s): "5"

Test #49:

score: 0
Accepted
time: 1ms
memory: 3412kb

input:

6 0

output:

12

result:

ok 1 number(s): "12"

Test #50:

score: 0
Accepted
time: 2ms
memory: 3452kb

input:

6 1
2 4 0

output:

11

result:

ok 1 number(s): "11"

Test #51:

score: 0
Accepted
time: 0ms
memory: 3432kb

input:

6 2
1 4 1
0 4 0

output:

10

result:

ok 1 number(s): "10"

Test #52:

score: 0
Accepted
time: 1ms
memory: 3472kb

input:

6 3
1 3 1
1 4 2
0 2 0

output:

9

result:

ok 1 number(s): "9"

Test #53:

score: 0
Accepted
time: 2ms
memory: 3416kb

input:

6 4
0 3 1
4 5 1
3 5 1
2 5 2

output:

10

result:

ok 1 number(s): "10"

Test #54:

score: 0
Accepted
time: 1ms
memory: 3492kb

input:

6 5
0 1 4
0 4 1
3 4 4
1 5 0
3 5 0

output:

9

result:

ok 1 number(s): "9"

Test #55:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

6 6
4 5 5
2 3 4
3 5 4
1 3 0
4 5 0
1 3 4

output:

9

result:

ok 1 number(s): "9"

Test #56:

score: 0
Accepted
time: 2ms
memory: 3440kb

input:

6 7
4 5 5
3 5 3
1 2 1
2 5 2
1 5 5
3 4 4
1 3 1

output:

7

result:

ok 1 number(s): "7"

Test #57:

score: 0
Accepted
time: 2ms
memory: 3480kb

input:

6 8
3 5 0
4 5 1
2 5 6
1 5 2
3 5 6
0 3 4
4 5 7
0 3 7

output:

7

result:

ok 1 number(s): "7"

Test #58:

score: 0
Accepted
time: 2ms
memory: 3496kb

input:

6 9
3 4 3
2 5 1
2 3 3
3 4 4
0 3 5
2 3 7
0 5 2
0 5 3
1 3 1

output:

7

result:

ok 1 number(s): "7"

Test #59:

score: 0
Accepted
time: 2ms
memory: 3472kb

input:

6 10
0 3 8
3 4 4
2 5 1
4 5 4
3 5 8
0 5 4
2 3 0
0 1 0
3 4 0
0 2 2

output:

7

result:

ok 1 number(s): "7"

Test #60:

score: 0
Accepted
time: 1ms
memory: 3524kb

input:

7 0

output:

14

result:

ok 1 number(s): "14"

Test #61:

score: 0
Accepted
time: 2ms
memory: 3520kb

input:

7 1
0 5 0

output:

13

result:

ok 1 number(s): "13"

Test #62:

score: 0
Accepted
time: 3ms
memory: 3496kb

input:

7 2
2 6 0
5 6 0

output:

13

result:

ok 1 number(s): "13"

Test #63:

score: 0
Accepted
time: 2ms
memory: 3480kb

input:

7 3
5 6 1
0 6 0
2 4 0

output:

12

result:

ok 1 number(s): "12"

Test #64:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

7 4
1 6 2
2 5 3
0 3 3
3 4 2

output:

12

result:

ok 1 number(s): "12"

Test #65:

score: 0
Accepted
time: 0ms
memory: 3436kb

input:

7 5
4 6 0
5 6 1
1 3 3
3 6 0
2 6 2

output:

10

result:

ok 1 number(s): "10"

Test #66:

score: 0
Accepted
time: 2ms
memory: 3496kb

input:

7 6
0 1 5
0 5 4
5 6 3
1 3 2
3 6 5
1 4 4

output:

10

result:

ok 1 number(s): "10"

Test #67:

score: 0
Accepted
time: 3ms
memory: 3480kb

input:

7 7
3 4 1
3 5 6
5 6 3
2 3 5
5 6 4
0 1 2
5 6 2

output:

9

result:

ok 1 number(s): "9"

Test #68:

score: 0
Accepted
time: 1ms
memory: 3432kb

input:

7 8
5 6 3
4 6 6
3 4 1
0 2 1
1 6 5
5 6 3
5 6 2
5 6 3

output:

10

result:

ok 1 number(s): "10"

Test #69:

score: 0
Accepted
time: 2ms
memory: 3484kb

input:

7 9
2 5 3
1 6 5
1 6 4
0 3 6
2 3 7
4 5 1
5 6 8
5 6 5
5 6 7

output:

8

result:

ok 1 number(s): "8"

Test #70:

score: 0
Accepted
time: 2ms
memory: 3420kb

input:

7 10
4 6 6
4 5 1
1 4 0
4 6 6
4 5 1
4 6 7
3 5 2
5 6 1
0 4 4
2 3 9

output:

8

result:

ok 1 number(s): "8"

Test #71:

score: 0
Accepted
time: 2ms
memory: 3488kb

input:

8 0

output:

16

result:

ok 1 number(s): "16"

Test #72:

score: 0
Accepted
time: 3ms
memory: 3416kb

input:

8 1
0 3 0

output:

15

result:

ok 1 number(s): "15"

Test #73:

score: 0
Accepted
time: 2ms
memory: 3424kb

input:

8 2
0 6 1
5 7 1

output:

15

result:

ok 1 number(s): "15"

Test #74:

score: 0
Accepted
time: 0ms
memory: 3460kb

input:

8 3
1 6 1
0 3 2
0 2 2

output:

14

result:

ok 1 number(s): "14"

Test #75:

score: 0
Accepted
time: 3ms
memory: 3468kb

input:

8 4
1 5 0
5 7 2
2 7 1
3 4 1

output:

13

result:

ok 1 number(s): "13"

Test #76:

score: 0
Accepted
time: 2ms
memory: 3472kb

input:

8 5
2 6 3
1 5 1
6 7 0
6 7 2
4 5 4

output:

12

result:

ok 1 number(s): "12"

Test #77:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

8 6
2 6 2
6 7 2
2 5 3
3 5 4
0 3 4
0 1 0

output:

12

result:

ok 1 number(s): "12"

Test #78:

score: 0
Accepted
time: 2ms
memory: 3544kb

input:

8 7
3 5 6
2 4 3
4 7 0
5 6 1
3 4 5
6 7 0
5 6 6

output:

11

result:

ok 1 number(s): "11"

Test #79:

score: 0
Accepted
time: 2ms
memory: 3524kb

input:

8 8
3 4 7
0 7 3
1 6 5
3 7 1
5 7 4
0 7 2
3 7 6
0 4 6

output:

10

result:

ok 1 number(s): "10"

Test #80:

score: 0
Accepted
time: 1ms
memory: 3536kb

input:

8 9
4 5 1
5 6 2
3 7 7
5 6 8
1 3 1
6 7 4
2 7 4
4 7 0
5 6 2

output:

11

result:

ok 1 number(s): "11"

Test #81:

score: 0
Accepted
time: 2ms
memory: 3444kb

input:

8 10
4 6 7
4 5 7
2 3 2
0 6 8
3 4 7
4 5 8
5 6 1
0 2 3
1 7 5
4 7 3

output:

10

result:

ok 1 number(s): "10"

Test #82:

score: 0
Accepted
time: 1ms
memory: 3520kb

input:

9 0

output:

18

result:

ok 1 number(s): "18"

Test #83:

score: 0
Accepted
time: 1ms
memory: 3456kb

input:

9 1
0 6 0

output:

17

result:

ok 1 number(s): "17"

Test #84:

score: 0
Accepted
time: 0ms
memory: 3536kb

input:

9 2
0 1 0
1 4 0

output:

17

result:

ok 1 number(s): "17"

Test #85:

score: 0
Accepted
time: 2ms
memory: 3420kb

input:

9 3
0 3 2
4 8 2
4 8 2

output:

17

result:

ok 1 number(s): "17"

Test #86:

score: 0
Accepted
time: 2ms
memory: 3468kb

input:

9 4
0 6 2
0 2 0
1 5 2
3 7 1

output:

15

result:

ok 1 number(s): "15"

Test #87:

score: 0
Accepted
time: 0ms
memory: 3428kb

input:

9 5
0 1 4
3 6 4
6 8 4
6 8 3
6 8 1

output:

16

result:

ok 1 number(s): "16"

Test #88:

score: 0
Accepted
time: 2ms
memory: 3544kb

input:

9 6
0 4 5
6 8 0
3 4 3
2 6 5
5 6 3
4 5 0

output:

15

result:

ok 1 number(s): "15"

Test #89:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

9 7
0 6 1
2 5 5
0 7 5
5 8 3
5 6 5
3 5 0
2 6 0

output:

14

result:

ok 1 number(s): "14"

Test #90:

score: 0
Accepted
time: 2ms
memory: 3468kb

input:

9 8
0 1 2
5 8 0
5 7 0
0 8 0
4 8 3
2 7 1
1 5 1
5 8 2

output:

14

result:

ok 1 number(s): "14"

Test #91:

score: 0
Accepted
time: 0ms
memory: 3464kb

input:

9 9
0 4 1
1 2 7
2 5 0
4 7 0
4 6 3
1 8 7
0 8 8
0 4 2
5 8 8

output:

13

result:

ok 1 number(s): "13"

Test #92:

score: 0
Accepted
time: 2ms
memory: 3492kb

input:

9 10
3 8 6
5 8 4
3 6 2
2 7 9
4 7 1
0 5 9
5 6 3
7 8 4
5 6 6
0 1 7

output:

11

result:

ok 1 number(s): "11"

Test #93:

score: 0
Accepted
time: 0ms
memory: 3520kb

input:

10 0

output:

20

result:

ok 1 number(s): "20"

Test #94:

score: 0
Accepted
time: 2ms
memory: 3412kb

input:

10 1
3 4 0

output:

19

result:

ok 1 number(s): "19"

Test #95:

score: 0
Accepted
time: 1ms
memory: 3532kb

input:

10 2
3 9 0
3 9 1

output:

19

result:

ok 1 number(s): "19"

Test #96:

score: 0
Accepted
time: 0ms
memory: 3432kb

input:

10 3
2 5 1
1 5 0
8 9 0

output:

18

result:

ok 1 number(s): "18"

Test #97:

score: 0
Accepted
time: 2ms
memory: 3492kb

input:

10 4
2 5 1
1 7 3
5 6 2
3 6 2

output:

17

result:

ok 1 number(s): "17"

Test #98:

score: 0
Accepted
time: 1ms
memory: 3472kb

input:

10 5
1 9 0
1 9 0
0 8 4
5 9 3
5 6 4

output:

17

result:

ok 1 number(s): "17"

Test #99:

score: 0
Accepted
time: 0ms
memory: 3448kb

input:

10 6
0 2 4
8 9 4
5 7 2
8 9 1
7 9 3
4 8 1

output:

16

result:

ok 1 number(s): "16"

Test #100:

score: 0
Accepted
time: 2ms
memory: 3528kb

input:

10 7
0 5 0
7 8 3
2 6 2
0 1 2
8 9 3
6 7 6
0 1 5

output:

15

result:

ok 1 number(s): "15"

Test #101:

score: 0
Accepted
time: 2ms
memory: 3484kb

input:

10 8
8 9 1
5 8 4
6 8 7
4 7 2
1 6 6
8 9 4
4 6 1
3 7 5

output:

14

result:

ok 1 number(s): "14"

Test #102:

score: 0
Accepted
time: 2ms
memory: 3468kb

input:

10 9
8 9 0
5 6 5
1 2 1
5 8 2
3 9 0
1 9 6
0 2 0
8 9 0
6 7 8

output:

14

result:

ok 1 number(s): "14"

Test #103:

score: 0
Accepted
time: 2ms
memory: 3516kb

input:

10 10
1 4 9
2 4 5
3 7 2
5 8 9
4 6 6
8 9 4
2 3 2
3 9 2
2 4 9
7 8 7

output:

14

result:

ok 1 number(s): "14"

Test #104:

score: 0
Accepted
time: 91ms
memory: 3716kb

input:

200 200
20 56 24
7 129 170
89 143 66
182 187 59
1 192 60
9 181 125
164 165 175
131 195 90
118 159 152
31 46 182
74 85 3
79 97 145
66 186 161
69 93 67
102 153 82
108 194 174
67 123 59
130 171 127
159 187 65
17 54 125
138 153 92
188 199 168
30 175 165
39 96 18
58 61 191
109 156 65
181 195 1
173 183 58...

output:

264

result:

ok 1 number(s): "264"

Test #105:

score: 0
Accepted
time: 192ms
memory: 3764kb

input:

200 400
6 148 31
37 91 362
22 116 182
168 173 279
140 149 370
55 176 208
96 115 21
65 109 58
52 180 342
46 112 203
97 116 237
151 187 77
63 151 132
35 49 75
115 120 151
188 197 194
13 138 68
32 40 113
60 69 284
127 151 73
189 194 351
125 191 188
103 166 355
79 174 161
57 149 158
15 185 238
39 52 343...

output:

131

result:

ok 1 number(s): "131"

Test #106:

score: -100
Time Limit Exceeded

input:

200 600
175 194 1
153 196 511
82 94 559
89 133 81
136 182 584
190 194 340
102 116 208
176 196 205
76 153 578
164 176 238
35 187 356
97 151 178
47 64 166
100 162 300
67 157 441
179 192 413
118 186 25
11 26 93
42 163 388
82 107 327
30 117 266
156 170 87
160 195 445
195 196 460
97 169 224
95 111 424
19...

output:


result: