Official

E - Sum of Max Matching Editorial by en_translator


First, we consider the property of \(f(x,y)\).

\(f(x,y)\) equals the minimum \(w\) such that vertices \(x\) and \(y\) are connected in the subgraph consisting of the edges with weights less than or equal to \(w\). Thus, for three distinct vertices \(x\), \(y\), and \(z\), if \(f(x,y) \leq f(x,z)\), then \(f(x,z)=f(y,z)\).

This implies that if two vertices \(x\) and \(y\) are connected via edges of weight no greater than \(w\), then any vertex \(z\) that is disconnected in the graph satisfies \(f(x,z)=f(y,z)\).

Also, instead of rearranging \(B\), this problem can be considered as a matching problem between the elements in \(A\) and the elements in \(B\).

Thus, we come up with the following greedy algorithm. Assume that the edges are sorted in ascending order of their weights, satisfying \(w_1 \leq w_2 \ldots \leq w_M\).

  • Initially, there is a graph with \(N\) vertices and no edges. We manage whether each vertex is contained in \(A\), and whether it is in \(B\).
  • For each \(i=1,2,\ldots,M\) in order, do the following.
    • If vertices \(u_i\) and \(v_i\) are disconnected, add edge \(\{u_i,v_i\}\) to the graph. If it is connected, go to the next edge.
    • If the addition made two different connected components connected, repeatedly match the vertices of \(A\) contained in one connected component with the vertices of \(B\) contained in the other as many times as possible.
    • Add \(w_i\) the number of new matches.
    • Update the vertices of \(A\) and \(B\) remaining in that connected component.

The matching between the elements in \(A\) and \(B\) constructed by this greedy algorithm is in fact an optimal solution.

In this problem, you do not actually need to find the matching between the elements in \(A\) and those in \(B\), so instead of managing the vertices themselves, we can manage the number of vertices that are elements of \(A\), and those in \(B\), including duplicates.

The connected components can be managed appropriately with a Disjoint Set Union. Since the edges are sorted once, so the complexity is \(\mathrm{O}(M\log M+(N+M) \alpha (N))\) (where \( \alpha(N)\) is the inverse Ackerman function). For more details, refer to the sample code.

Sample code (C++):

#include <bits/stdc++.h>
#include <atcoder/dsu>
using namespace std;
using ll = long long;
static constexpr ll inf = 2e18;

int main() {
    int n, m, k;
    cin >> n >> m >> k;
    vector<tuple<int, int, int>> edges(m);
    vector<int> a(k), b(k);
    for (int i = 0; i < m; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        u--, v--;
        edges[i] = {w, u, v};
    }
    for (int i = 0; i < k; ++i) cin >> a[i];
    for (int i = 0; i < k; ++i) cin >> b[i];

    vector<int> cnt_a(n), cnt_b(n); // the number of members of A and B in each connected component
    for (int i = 0; i < k; ++i) {
        cnt_a[a[i] - 1]++;
        cnt_b[b[i] - 1]++;
    }
    sort(edges.begin(), edges.end());
    long long ans = 0;
    atcoder::dsu d(n);
    for (int i = 0; i < m; ++i) {
        auto [c, u, v] = edges[i];
        if (d.same(u, v)) continue; // ignore if they are already connected
        int ru = d.leader(u), rv = d.leader(v);
        d.merge(u, v);
        int new_root = d.leader(u);
        cnt_a[new_root] = cnt_a[ru] + cnt_a[rv];
        cnt_b[new_root] = cnt_b[ru] + cnt_b[rv];
        ans += 1LL * c * min(cnt_a[new_root], cnt_b[new_root]); // pair as many times as possible
        const int e = min(cnt_a[new_root], cnt_b[new_root]);
        cnt_a[new_root] -= e;
        cnt_b[new_root] -= e;
    }

    cout << ans << endl;
}

posted:
last update: