質問するログイン新規登録

Q&A

解決済

1回答

324閲覧

【Atcoder】Typical Contest 001 問題B Union Findの不正解の理由が分からない

catworld

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

AtCoder

AtCoderは、日本の競技プログラミングサイト「AtCoder」に関する内容です。

0グッド

2クリップ

投稿2026/04/13 17:43

編集2026/04/14 03:21

0

2

質問内容

AtCoder Typical Contest 001 問題B Union Find(https://atcoder.jp/contests/atc001/tasks/unionfind_a ) に関する質問です.
この問題に対して以下の3パターンのプログラムを提出したところ,以下のような結果になりました.

パターン1:WA(不正解)
https://atcoder.jp/contests/atc001/submissions/74948369

パターン2:AC(正解)
変更点:パターン1の14行目をself.parent[ax] = ayからself.parent[ay] = axに変更
https://atcoder.jp/contests/atc001/submissions/74948437

パターン3:AC(正解)
変更点:パターン1の7行目をself.parent = [-1]*nからself.parent = [i for i in range(n)],17行目をif self.parent[x] == -1:からif self.parent[x] == x:に変更
https://atcoder.jp/contests/atc001/submissions/74948448

私の理解ではパターン1~3は本質的に違いはないと思われますが,
パターン1だけWAになる理由がどうしても分かりません.ご教授お願い致します.

補足情報

言語:Python(CPython 3.13.7)
不正解のテストケースの内容は非公開

プログラム

Python

1# パターン1 2import sys 3sys.setrecursionlimit(10**7) 4 5class UnionFind: 6 def __init__(self, n:int): 7 self.parent = [-1]*n 8 9 def union(self, x:int, y:int): 10 ax = self.find(x) 11 ay = self.find(y) 12 if ax == ay: 13 return 14 self.parent[ax] = ay 15 16 def find(self, x:int): 17 if self.parent[x] == -1: 18 return x 19 self.parent[x] = self.find(self.parent[x]) 20 return self.parent[x] 21 22 def same(self, x:int, y:int): 23 return self.find(x) == self.find(y) 24 25# 以下共通部分 26n,q = (int(a) for a in input().split()) 27uf = UnionFind(n) 28ans = [] 29 30for _ in range(q): 31 p,a,b = (int(x) for x in input().split()) 32 if p==0: 33 uf.union(a-1,b-1) 34 else: 35 ans.append(uf.same(a-1,b-1)) 36 37for b in ans: 38 if b: 39 print('Yes') 40 else: 41 print('No')

Python

1# パターン2 2import sys 3sys.setrecursionlimit(10**7) 4 5class UnionFind: 6 def __init__(self, n:int): 7 self.parent = [-1]*n 8 9 def union(self, x:int, y:int): 10 ax = self.find(x) 11 ay = self.find(y) 12 if ax == ay: 13 return 14 self.parent[ay] = ax # 変更点 15 16 def find(self, x:int): 17 if self.parent[x] == -1: 18 return x 19 self.parent[x] = self.find(self.parent[x]) 20 return self.parent[x] 21 22 def same(self, x:int, y:int): 23 return self.find(x) == self.find(y)

Python

1# パターン3 2import sys 3sys.setrecursionlimit(10**7) 4 5class UnionFind: 6 def __init__(self, n:int): 7 self.parent = [i for i in range(n)] # 変更点 8 9 def union(self, x:int, y:int): 10 ax = self.find(x) 11 ay = self.find(y) 12 if ax == ay: 13 return 14 self.parent[ax] = ay 15 16 def find(self, x:int): 17 if self.parent[x] == x: # 変更点 18 return x 19 self.parent[x] = self.find(self.parent[x]) 20 return self.parent[x] 21 22 def same(self, x:int, y:int): 23 return self.find(x) == self.find(y)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答1

0

ベストアンサー

原因は、UnionFindの実装ではなく、共通部分の不具合になります。

問題の「入力」の欄に、​(0≦Ai​,Bi​≦N−1)と書かれていますが、共通部分のコードは、(1≦Ai​,Bi​≦N)を前提として書かれています。

念のため、同じ現象を再現する入力を示しておきます。

2 2 0 1 0 1 1 0

投稿2026/04/14 02:41

actorbug

総合スコア2564

catworld

2026/04/14 03:40

Pythonのリストは負の値でも参照できることをすっかり忘れていました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.25%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問