# Detecting cycles in a given adjacency list # First we're given N for how many nodes we'll have n = int(input()) # Next we're given the N nodes class Node: def __init__(self, name, in_degree=0): self.name = name self.in_degree = in_degree def __str__(self): return self.name def __repr__(self): return f'{self.name} {self.in_degree}' nodes = [] for i in range(0, n): nodes.append(Node(input().strip())) # Next we're given how many nodes and edges we have total ex:n e _node_count, _edge_count = input().split() _node_count = int(_node_count) _edge_count = int(_edge_count) edges = [] for i in range(0, _edge_count): _from, _to = input().split() edges.append([int(_from), int(_to)]) # Now we calculate the in-degrees for edge in edges: # take the target index in nodes and increment its in_degree nodes[edge[1]].in_degree += 1 # Quick check if we exceed the max count of edges max_edges = ((_node_count//2) * (_node_count -1))+1 #print(f'{_edge_count}/{max_edges}') if _edge_count >= max_edges: print('Cycle!') exit(0) # building the queue of items based on in-degrees def add_nodes(_deg): ret = [] for i in nodes: if i.in_degree == _deg: ret.append(i) return ret def find_neighbors(node): ret = [] for i in edges: if i[1] == nodes.index(node): ret.append(nodes[i[0]]) nodes_mirror = [i for i in nodes] # add the lowest in-degree nodes to our queue, up to the higher ones budget_q = [] for i in range(0, max_edges): budget_q += add_nodes(i) visited = [] i = 0 while len(budget_q) > 0: # add the first thing to the visited list #visited.append(budget_q[0]) # Decrememt the neighbors' in_degree for i in edges: _from = i[0] _to = i[1] if nodes[_from] == budget_q[0]: _neighbor = nodes_mirror[_to] _neighbor.in_degree -= 1 if _neighbor.in_degree == 0: visited.append(nodes_mirror[_to]) budget_q.append(_neighbor) # remove whats at the front del budget_q[0] # then compare the lenthts if len(visited) != (len(nodes) + len(edges)): print('Cycle!') else: print('No cycle!')