AtCoder

ABC372 E問題(K-th Largest Connected Components)を解く

AtCoder_ABC372_E

AtCoder が提供しているABC(AtCoder Beginner Contest)372 E問題をC++で解いてみました。ABC372は、2024年9月21日21:00に実施されました。

AtCoder の紹介はこちらに、プログラミングの方針はこちらに記事があります。

E問題 K-th Largest Connected Components(Difficulty : 1042)

問題の詳細は、リンク先をご覧ください。

ABC372 E問題 K-th Largest Connected Components

UnionFindで統合したときに番号の大きな頂点を再計算します。AtCoder Problems による Difficulty は 1042 でした。

解答案

UnionFind で統合したときに、頂点が大きな順に番号を配列に格納します。$1 \leqq k \leqq 10$ であるため、最大10個格納すればクエリの処理ができます。

C++ プログラム例(ABC372E)

プログラムの補足です。

  • ACL(AtCoder Library)の UnionFind を使います(2、4行目)。
  • それぞれの頂点と連結している頂点番号の順に配列 points に最大10個記憶します。
    • 初期値は、その頂点自身しかありません(24ー27行目)。
    • タイプ1のクエリでは、関数 merge_vpoints を更新します(6ー18行目)。
  • タイプ2のクエリでは、指定された頂点と連結している $k$ 番目の頂点番号の要素を出力します。

以下が、C++プログラムです。

#include <bits/stdc++.h>
#include <atcoder/dsu>
using namespace std;
using namespace atcoder;

void merge_v(vector<int>& u_vector, vector<int>& v_vector)
{
	vector<int> t = u_vector;
	for (int i = 0; i < (int)v_vector.size(); ++i) {
		t.push_back(v_vector[i]);
	}

	sort(t.begin(), t.end(), greater<int>());
	u_vector.clear();
	for (int i = 0; i < min(10, (int)t.size()); ++i) {
		u_vector.push_back(t[i]);
	}
}

int main()
{
	int n, q;
	cin >> n >> q;
	vector<vector<int>> points(n + 1);
	for (int i = 1; i <= n; ++i) {
		points[i].push_back(i);
	}

	dsu uf(n + 1);
	for (int i = 0; i < q; ++i) {
		int type;
		cin >> type;
		if (type == 1) {
			int u, v;
			cin >> u >> v;
			if (!uf.same(u, v)) {
				int pre_u = uf.leader(u);
				int pre_v = uf.leader(v);
				uf.merge(u, v);
				if (uf.leader(u) == pre_u) {
					merge_v(points[pre_u], points[pre_v]);
				} else {
					merge_v(points[pre_v], points[pre_u]);
				}
			}
		} else if (type == 2) {
			int v, k;
			cin >> v >> k;
			if ((int)points[uf.leader(v)].size() < k) {
				cout << -1 << endl;
			} else {
				cout << points[uf.leader(v)][k - 1] << endl;
			}
		}
	}

	return 0;
}

AC(Accepted=正しいプログラム)と判定されました。

Python は、標準ライブラリで UnionFind がありません。プログラムの紹介を省略します。

最後に

$k$ の制約が小さいことがポイントでした。UnionFind について理解を深めることができました。

引き続き ABC の問題を紹介していきます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA