結果
問題 | No.1023 Cyclic Tour |
ユーザー |
![]() |
提出日時 | 2025-03-20 21:16:58 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,850 bytes |
コンパイル時間 | 275 ms |
コンパイル使用メモリ | 82,512 KB |
実行使用メモリ | 209,748 KB |
最終ジャッジ日時 | 2025-03-20 21:18:18 |
合計ジャッジ時間 | 28,039 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 46 WA * 3 |
ソースコード
import sysfrom collections import defaultdict, dequesys.setrecursionlimit(1 << 25)class UnionFind:def __init__(self, size):self.parent = list(range(size + 1))self.rank = [0] * (size + 1)def find(self, x):if self.parent[x] != x:self.parent[x] = self.find(self.parent[x])return self.parent[x]def unite(self, x, y):x = self.find(x)y = self.find(y)if x == y:returnif self.rank[x] < self.rank[y]:self.parent[x] = yelse:self.parent[y] = xif self.rank[x] == self.rank[y]:self.rank[x] += 1def main():import sysinput = sys.stdin.readdata = input().split()idx = 0N = int(data[idx])idx += 1M = int(data[idx])idx +=1undirected = []directed = []directed_edges_set = set()for _ in range(M):a = int(data[idx])idx +=1b = int(data[idx])idx +=1c = int(data[idx])idx +=1if c == 1:undirected.append( (a, b) )else:directed.append( (a, b) )directed_edges_set.add( (a, b) )# Step 1: Check cycles in undirected subgraphuf = UnionFind(N)for a, b in undirected:uf.unite(a, b)uni_v = defaultdict(int)uni_e = defaultdict(int)for i in range(1, N+1):root = uf.find(i)uni_v[root] += 1for a, b in undirected:root_a = uf.find(a)root_b = uf.find(b)if root_a == root_b:uni_e[root_a] += 1for root in uni_v:if uni_e[root] >= uni_v[root]:print("Yes")return# Step 2: Check cycles in directed subgraph using SCCgraph = [[] for _ in range(N+1)]for a, b in directed:graph[a].append(b)visited = [False] * (N + 1)order = []for i in range(1, N + 1):if not visited[i]:stack = [(i, False)]while stack:node, processed = stack.pop()if processed:order.append(node)continueif visited[node]:continuevisited[node] = Truestack.append( (node, True) )for neighbor in reversed(graph[node]):if not visited[neighbor]:stack.append( (neighbor, False) )visited = [False] * (N + 1)components = []reverse_graph = [[] for _ in range(N+1)]for v in range(1, N+1):for u in graph[v]:reverse_graph[u].append(v)for v in reversed(order):if not visited[v]:component = []stack = [v]visited[v] = Truewhile stack:node = stack.pop()component.append(node)for neighbor in reverse_graph[node]:if not visited[neighbor]:visited[neighbor] = Truestack.append(neighbor)components.append(component)for comp in components:if len(comp) >= 2:print("Yes")return# Step 3: Check if any undirected edge's reverse is a directed edgefor a, b in undirected:if (b, a) in directed_edges_set:print("Yes")return# Step 4: Contract the graph and check for cyclescomponent_representative = {}for i in range(1, N+1):component_representative[i] = uf.find(i)comp_ids = {}id_counter = 0for root in component_representative.values():if root not in comp_ids:comp_ids[root] = id_counterid_counter += 1nodes = id_countercontracted_graph = [[] for _ in range(nodes)]edge_set = set()for a, b in directed:a_root = component_representative[a]b_root = component_representative[b]u = comp_ids[a_root]v = comp_ids[b_root]if u != v and (u, v) not in edge_set:contracted_graph[u].append(v)edge_set.add( (u, v) )# Check if DAGin_degree = [0] * nodesfor u in range(nodes):for v in contracted_graph[u]:in_degree[v] += 1q = deque()for u in range(nodes):if in_degree[u] == 0:q.append(u)visited = 0while q:u = q.popleft()visited += 1for v in contracted_graph[u]:in_degree[v] -= 1if in_degree[v] == 0:q.append(v)if visited != nodes:print("Yes")returnprint("No")if __name__ == "__main__":main()