Python3で書いたはじめてのクラスなので、もっと簡潔な表現ができるかもしれないが、自己メモとして置いておく。

Union Setは2つの要素が同一集合に属するかどうか、効率的に判定できるアルゴリズム。構造が簡単で、競プロではよく見かける。

使い方は簡単。
u = UnionSet(nmax)  # クラスの生成。nmaxは集合の最大値
u.unite(a, b)  # 整数 a, b を同一集合にする
u.connected(a, b)  # 整数 a, b は同一集合に属するかどうかを聞く
u.root(a)  # 整数 a が属する集合の代表値(ルート値)

以下はコード。AOJ-ALDS1_11_Dに対する解答でもある。

# AOJ ALDS1_11_D Connected Components
# Python3 2018.6.23 bal4u

# UNION-FIND library
class UnionSet:
	def __init__(self, nmax):
		self.size = [1]*nmax
		self.id = [i for i in range(nmax+1)]
	def root(self, i):
		while i != self.id[i]:
			self.id[i] = self.id[self.id[i]]
			i = self.id[i]
		return i
	def connected(self, p, q): return self.root(p) == self.root(q)
	def unite(self, p, q):
		i, j = self.root(p), self.root(q)
		if i == j: return
		if self.size[i] < self.size[j]:
			self.id[i] = j
			self.size[j] += self.size[i]
		else:
			self.id[j] = i
			self.size[i] += self.size[j]
# UNION-FIND library

n, m = map(int, input().split())
u = UnionSet(n)
for i in range(m):
	s, t = map(int, input().split())
	u.unite(s, t)
q = int(input())
for i in range(q):
	s, t = map(int, input().split())
	print("yes" if u.connected(s, t) else "no")

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Post Navigation