結果
問題 | No.1983 [Cherry 4th Tune C] 南の島のマーメイド |
ユーザー | 👑 Kazun |
提出日時 | 2024-02-12 11:24:29 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,457 ms / 4,000 ms |
コード長 | 9,712 bytes |
コンパイル時間 | 265 ms |
コンパイル使用メモリ | 82,448 KB |
実行使用メモリ | 262,736 KB |
最終ジャッジ日時 | 2024-09-28 17:55:26 |
合計ジャッジ時間 | 31,670 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 39 ms
56,700 KB |
testcase_01 | AC | 39 ms
56,304 KB |
testcase_02 | AC | 38 ms
56,788 KB |
testcase_03 | AC | 37 ms
55,996 KB |
testcase_04 | AC | 36 ms
56,296 KB |
testcase_05 | AC | 37 ms
56,088 KB |
testcase_06 | AC | 37 ms
56,032 KB |
testcase_07 | AC | 37 ms
56,940 KB |
testcase_08 | AC | 164 ms
80,444 KB |
testcase_09 | AC | 207 ms
83,292 KB |
testcase_10 | AC | 198 ms
83,452 KB |
testcase_11 | AC | 217 ms
84,596 KB |
testcase_12 | AC | 204 ms
82,384 KB |
testcase_13 | AC | 779 ms
146,160 KB |
testcase_14 | AC | 776 ms
152,944 KB |
testcase_15 | AC | 1,027 ms
181,652 KB |
testcase_16 | AC | 521 ms
156,416 KB |
testcase_17 | AC | 868 ms
156,940 KB |
testcase_18 | AC | 1,038 ms
179,456 KB |
testcase_19 | AC | 1,314 ms
203,156 KB |
testcase_20 | AC | 974 ms
174,352 KB |
testcase_21 | AC | 951 ms
171,176 KB |
testcase_22 | AC | 1,026 ms
174,392 KB |
testcase_23 | AC | 1,423 ms
212,992 KB |
testcase_24 | AC | 1,454 ms
213,516 KB |
testcase_25 | AC | 1,434 ms
213,308 KB |
testcase_26 | AC | 1,443 ms
214,928 KB |
testcase_27 | AC | 1,421 ms
212,752 KB |
testcase_28 | AC | 1,413 ms
214,316 KB |
testcase_29 | AC | 1,436 ms
214,516 KB |
testcase_30 | AC | 1,449 ms
214,400 KB |
testcase_31 | AC | 1,428 ms
215,808 KB |
testcase_32 | AC | 1,457 ms
214,032 KB |
testcase_33 | AC | 40 ms
56,264 KB |
testcase_34 | AC | 361 ms
154,396 KB |
testcase_35 | AC | 527 ms
204,028 KB |
testcase_36 | AC | 560 ms
194,676 KB |
testcase_37 | AC | 39 ms
56,668 KB |
testcase_38 | AC | 99 ms
81,820 KB |
testcase_39 | AC | 589 ms
226,604 KB |
testcase_40 | AC | 644 ms
262,736 KB |
ソースコード
class Graph: __slots__=("edge_offset", "edge_alive", "edge_ids", "vertex_alive", "adjacent", "deg") #入力定義 def __init__(self, N = 0, edge_offset = 0): """ N 頂点の空グラフ (多重辺なし) を生成する.""" self.adjacent = [[] for _ in range(N)] self.edge_ids = [[] for _ in range(N)] self.vertex_alive = [1] * N self.edge_offset = edge_offset self.edge_alive = [0] * edge_offset self.deg = [0] * N #頂点の追加 def add_vertex(self): """ 頂点を追加する. """ self.adjacent.append([]) self.edge_ids.append([]) self.vertex_alive.append(1) self.deg.append(0) return self.order() - 1 def add_vertices(self, k): """ 頂点を k 個追加する. k: int """ n=self.order() self.adjacent.extend([[] for _ in range(k)]) self.edge_ids.extend([[] for _ in range(k)]) self.vertex_alive.extend([1] * k) self.deg.extend([0] * k) return list(range(n, n + k)) #辺の追加 def add_edge(self, u, v): """ 無向辺 uv を加える""" j = len(self.edge_alive) self.adjacent[u].append(v) self.adjacent[v].append(u) self.edge_ids[u].append(j) self.edge_ids[v].append(j) self.deg[u] += 1; self.deg[v] += 1 self.edge_alive.append(1) return j #辺を除く def remove_edge(self,u,v): """ 無向辺 uv が存在するならば除く""" pass def reset_vertex(self, u): """ 頂点 u に接続している辺を全て消す.""" pass #Walkの追加 def add_walk(self, *walk): """ walk=(w[0],...,w[n-1]) に対して, n-1 本の辺 w[i]w[i+1] を加える.""" for i in range(len(walk) - 1): self.add_edge(walk[i], walk[i + 1]) #Cycleの追加 def add_cycle(self, *cycle): """ cycle=(c[0], ..., c[n-1]) を加える. """ self.add_walk(*cycle) self.add_edge(cycle[-1], cycle[0]) #グラフに辺が存在するか否か def edge_exist(self, u, v): """ 辺 uv が存在するか? """ pass def partner(self, v): adj = self.adjacent[v] edge_ids = self.edge_ids[v] return [adj[k] for k in range(len(edge_ids)) if self.edge_alive[edge_ids[k]]] def partner_with_index(self, v): adj = self.adjacent[v] edge_ids = self.edge_ids[v] return [(adj[k], edge_ids[k]) for k in range(len(edge_ids)) if self.edge_alive[edge_ids[k]]] #近傍 def neighborhood(self, v): """ 頂点 v の近傍を求める. """ adj = self.adjacent[v] edge_ids = self.edge_ids[v] return list(set(adj[k] for k in range(len(edge_ids)) if self.edge_alive[edge_ids[k]])) #次数 def degree(self, v): """ 頂点 v の次数を求める. """ return self.deg[v] #頂点数 def vertex_count(self): """ グラフの頂点数 (位数) を出力する. """ return len(self.adjacent) def order(self): """ グラフの位数 (頂点数) を出力する. """ return len(self.adjacent) #辺数 def edge_count(self): """ 辺の本数 (サイズ) を出力する.""" return len(self.edge_alive) - self.edge_offset def size(self): """ サイズ (辺の本数) を出力する. """ return len(self.edge_alive) - self.edge_offset #頂点vを含む連結成分 def connected_component(self, v): """ 頂点 v を含む連結成分を出力する.""" N = self.order() stack = [v] comp = [0] * N; comp[v] = 1 while stack: x = stack.pop() for y in self.neighborhood(x): if comp[y] == 0: comp[y] = 1 stack.append(y) return [x for x in range(N) if comp[x]] #距離 def distance(self, u, v, default): """ 2頂点 u,v 間の距離を求める.""" if u == v: return 0 from collections import deque N = self.order() dist = [-1] * N; dist[u]=0 queue = deque([u]) while queue: x = queue.popleft() for y in self.neighborhood(x): if dist[y] == -1: dist[y] = dist[x] + 1 queue.append(y) if y == v: return dist[v] return default #ある1点からの距離 def distance_all(self,u,default=-1): """ 頂点 u からの距離を求める.""" from collections import deque N = self.order() dist = [-1] * N; dist[u]=0 queue = deque([u]) while queue: x = queue.popleft() for y in self.neighborhood(x): if dist[y] == -1: dist[y] = dist[x] + 1 queue.append(y) return [dist[x] if dist[x] != -1 else default for x in range(N)] #最短路 def shortest_path(self, u, v): """ u から v への最短路を求める (存在しない場合は None). """ if u == v: return [u] from collections import deque prev = [-1] * self.order() prev[u] = u queue = deque([u]) while queue: x = queue.popleft() for y in self.adjacent[x]: if prev[x] != -1: continue prev[y] = x queue.append(y) if y != v: continue path = [v] a = v while a != u: a = prev[a] path.append(a) return path[::-1] return None def edge_yielder(self): u = [0] * len(self.edge_alive); v = [0] * len(self.edge_alive) for x in range(self.order()): adj = self.adjacent[x] ids = self.edge_ids[x] for k in range(len(adj)): id = ids[k] u[id] = min(x, adj[k]) v[id] = max(x, adj[k]) for id in range(len(self.edge_alive)): if self.edge_alive[id]: yield (u[id], v[id]) def edge_yielder_with_index(self): u = [0] * len(self.edge_alive); v = [0] * len(self.edge_alive) for x in range(self.order()): adj = self.adjacent[x] ids = self.edge_ids[x] for k in range(len(adj)): id = ids[k] u[id] = min(x, adj[k]) v[id] = max(x, adj[k]) for id in range(len(self.edge_alive)): if self.edge_alive[id]: yield (id, u[id], v[id]) def Lowlink(G: Graph, mode=0): """ G の ord, lowlink を求める. G: Graph output: (ord, lowlink) """ from collections import deque N=G.vertex_count() ord=[-1]*N; low=[-1]*N flag=[0]*N adj=G.adjacent parent=[-1]*N #BFSパート for v in range(N): if flag[v]: continue k=0 S=deque([v]) T=[] while S: u=S.pop() if flag[u]: continue T.append(u) ord[u]=k k+=1 flag[u]=1 for w in G.neighborhood(u): if not flag[w]: S.append(w) parent[w]=u for u in T: low[u]=ord[u] for w in T[:0:-1]: for x in adj[w]: if w==v or x!=parent[w]: low[w]=min(low[w],low[x],ord[x]) if mode==0: return ord, low else: return ord, low, parent #橋列挙 def Bridge(G: Graph): """ G にある橋の id を列挙する. G: Graph """ ord, low = Lowlink(G) return [id for id, u, v in G.edge_yielder_with_index() if (ord[u] < low[v]) or (ord[v] < low[u])] #連結成分に分解 def Connected_Component_Decomposition(G: Graph, mode = 0): """ 連結成分毎に分解する. G: Graph mode:0 → 連結成分, 1 → 連結成分番号, 2 → (連結成分, 連結成分番号)""" comp_id = [-1] * G.order() comps = [] def dfs(start, id): stack = [start] comp_id[start] = id comp = [] while stack: x = stack.pop() comp.append(x) for y in G.neighborhood(x): if comp_id[y] == -1: comp_id[y] = id stack.append(y) comps.append(comp) id = 0 for x in range(G.order()): if comp_id[x] == -1: dfs(x, id) id += 1 if mode == 0: return comps elif mode == 1: return comp_id elif mode == 2: return (comps, comp_id) #================================================== def solve(): N, M, Q = map(int, input().split()) G = Graph(N + 1) for j in range(M): u, v = map(int, input().split()) G.add_edge(u, v) bridges = set(Bridge(G)) H = Graph(N + 1) for j, u, v in G.edge_yielder_with_index(): if j in bridges: H.add_edge(u, v) comp_id = Connected_Component_Decomposition(H, 1) ans = [False] * Q for q in range(Q): x, y = map(int, input().split()) ans[q] = (comp_id[x] == comp_id[y]) return ans #================================================== import sys input=sys.stdin.readline write=sys.stdout.write write("\n".join(map(str, ["Yes" if ans else "No" for ans in solve()])))