結果
問題 | No.1983 [Cherry 4th Tune C] 南の島のマーメイド |
ユーザー |
![]() |
提出日時 | 2022-09-16 16:55:13 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
AC
|
実行時間 | 3,177 ms / 4,000 ms |
コード長 | 4,113 bytes |
コンパイル時間 | 110 ms |
コンパイル使用メモリ | 12,928 KB |
実行使用メモリ | 149,672 KB |
最終ジャッジ日時 | 2024-12-21 13:51:06 |
合計ジャッジ時間 | 63,530 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 41 |
ソースコード
def resolve():import sysinput = sys.stdin.readlinen, m, q = map(int, input().split())edges = [[] for _ in range(n)]uf = UnionFind(n)for _ in range(m):u, v = map(lambda x: int(x) - 1, input().split())edges[u].append(v)edges[v].append(u)uf.union(u, v)u = UnionFind(n)for v in uf.all_group_members().values():d = {j: i for i, j in enumerate(v)}edge = [[] for _ in range(len(v))]for i, j in enumerate(v):for k in edges[j]:edge[i].append(d[k])bridge = bridge_detection(edge)for i, j in bridge:u.union(v[i], v[j])for _ in range(q):x, y = map(lambda x: int(x) - 1, input().split())if u.same(x, y):print("Yes")else:print("No")def bridge_detection(edges, start=0):n = len(edges)ord = [-1] * norder = ord[:]low = ord[:]q = [(start, -1)]cnt = 0edge = [[] for _ in range(n)]while q:i, pos = q.pop()if ord[i] >= 0:edge[i].append(pos)continueif pos >= 0:edge[pos].append(i)ord[i] = cntorder[cnt] = icnt += 1for j in reversed(edges[i]):if j == pos or ord[j] >= 0:continueq.append((j, i))for i, j in enumerate(reversed(order)):low[j] = n - i - 1for k in edge[j]:if ord[k] < low[j]:low[j] = ord[k]if low[k] >= 0 and low[k] < low[j]:low[j] = low[k]bridges = []for i, j in enumerate(edge):for k in j:if ord[i] < low[k]:bridges.append((i, k))return bridgesclass UnionFind:def __init__(self, n: int) -> None:self.n = nself.parent = [-1] * nself.groups = ndef find(self, x: int) -> int:if self.parent[x] < 0:return xelse:p = xwhile self.parent[p] >= 0:p = self.parent[p]while self.parent[x] >= 0:self.parent[x], x = p, self.parent[x]return pdef union(self, x: int, y: int) -> bool:x = self.find(x)y = self.find(y)if x == y:return Falseif self.parent[x] > self.parent[y]:x, y = y, xself.parent[x] += self.parent[y]self.parent[y] = xself.groups -= 1return Truedef union_right(self, x: int, y: int) -> bool:x = self.find(x)y = self.find(y)if x == y:return Falseif y > x:x, y = y, xself.parent[x] += self.parent[y]self.parent[y] = xself.groups -= 1return Truedef union_left(self, x: int, y: int) -> bool:x = self.find(x)y = self.find(y)if x == y:return Falseif x > y:x, y = y, xself.parent[x] += self.parent[y]self.parent[y] = xself.groups -= 1return Truedef size(self, x: int) -> int:return -self.parent[self.find(x)]def same(self, x: int, y: int) -> bool:return self.find(x) == self.find(y)def members(self, x: int) -> list:root = self.find(x)return [i for i in range(self.n) if self.find(i) == root]def roots(self) -> list:return [i for i, x in enumerate(self.parent) if x < 0]def group_count(self) -> int:return self.groupsdef sizes(self) -> dict:return {i: -x for i, x in enumerate(self.parent) if x < 0}def all_group_members(self) -> dict:from collections import defaultdictd = defaultdict(list)for i in range(self.n):p = self.find(i)d[p].append(i)return ddef __str__(self) -> str:return '\n'.join('{}: {}'.format(k, v)for k, v in self.all_group_members().items())if __name__ == '__main__':resolve()