結果

問題 No.583 鉄道同好会
ユーザー sjikisjiki
提出日時 2021-09-12 22:33:46
言語 Python3
(3.12.2 + numpy 1.26.4 + scipy 1.12.0)
結果
WA  
実行時間 -
コード長 2,171 bytes
コンパイル時間 192 ms
コンパイル使用メモリ 10,976 KB
実行使用メモリ 15,384 KB
最終ジャッジ日時 2023-09-07 00:39:08
合計ジャッジ時間 4,427 ms
ジャッジサーバーID
(参考情報)
judge12 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 17 ms
8,140 KB
testcase_01 AC 17 ms
8,124 KB
testcase_02 WA -
testcase_03 AC 17 ms
8,072 KB
testcase_04 AC 17 ms
8,180 KB
testcase_05 WA -
testcase_06 AC 17 ms
8,068 KB
testcase_07 AC 16 ms
8,188 KB
testcase_08 WA -
testcase_09 WA -
testcase_10 AC 17 ms
8,476 KB
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 AC 514 ms
15,384 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class UnionFind:
    def __init__(self, n):
        self.parent = [-1] * n
        self.n = n
        self.cnt = n

    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]

    def merge(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        if self.parent[x] > self.parent[y]:
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        self.cnt -= 1
        return True

    def same(self, x, y):
        return self.root(x) == self.root(y)

    def size(self, x):
        return -self.parent[self.root(x)]

    def count(self):
        return self.cnt

    def groups(self):
        res = [[] for _ in range(self.n)]
        for i in range(self.n):
            res[self.root(i)].append(i)
        return [group for group in res if group]


def is_eulerian(digraph):
    n = len(digraph)
    diffs = [0] * n  # diff = outdeg - indeg
    uf = UnionFind(n)
    vs = set([])
    for v in range(n):
        for nxt_v in digraph[v]:
            diffs[v] += 1
            diffs[nxt_v] -= 1
            uf.merge(v, nxt_v)
            vs.add(v)
            vs.add(nxt_v)
    if len(vs) - n + uf.count() != 1:
        # 非連結な路が存在するので有向オイラー路が存在しない
        return False, -1, -1
    if diffs.count(0) == n:
        # 有向オイラー閉路
        return True, -1, -1
    s, t = [], []
    for v, diff in enumerate(diffs):
        if diff == 1:
            s.append(v)
        if diff == -1:
            t.append(v)
    if len(s) == 1 and len(t) == 1:
        # 始点 s[0], 終点 t[0] の有向オイラー路
        return True, s[0], t[0]
    else:
        # 有向オイラー路が存在しない
        return False, -1, -1


n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a) 

judge, s, t = is_eulerian(graph)
if judge and s == -1 and t == -1:
    print("YES")
else:
    print("NO")
0