AT274の技術だったりなかったり

あっとのTECH LOG

競プロのこととか技術のこととか。たまに日常を書きます。

ABC126 E - 1 or 2

問題原文

atcoder.jp

問題要旨

 N 枚のカードが裏向きに置かれている。各カードには 1 または 2 が書かれている。
また「 xi 番目のカードと  yi 番目のカードに  Z を加えた値は偶数」という情報が   M 個与えられる。
最低何枚のカードをめくれば、全てのカードについて書かれている数を当てることができるか?

  •   1 \leq N \leq 10^{5}
  •   1 \leq M \leq 10^{5}
  •   1 \leq Z \leq 100

解法

まず、  Z の値はどうでもいい。つまり、各情報は 「 xi 番目のカードと  y_i 番目のカードの和の偶奇を知れると」して良い。
また、  xi 番目のカードがわかれば、 各カードに書かれている数は 1 か 2なのだから、結局  y_i 番目のカードもわかる。
そして、  y_i 番目のカードがわかれば、  y_i 番目に紐づく情報を持つカードの情報は、結局芋づる式にわかってしまう。

結局求めたいのは、「情報が連鎖していくグループがいくつあるか?」になったので、これはUnionFindなどを用いて数えればよい。

実装

N, M = map(int, input().split())

UF = UnionFind(N)
for i in range(M):
    x, y, z = map(int, input().split())
    x, y = x - 1, y - 1
    UF.union(x, y)
UF.all_find()  # 全ノードについてfind
 
print(len(set(UF.par)))

感想

本番5分とかで思いついたらしい。
UFだいすき!