Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

1 рік тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import random
  2. import itertools
  3. import copy
  4. import collections
  5. def make_graph(text):
  6. graph = collections.defaultdict(set)
  7. for aa, *bbs in map(str.split, text.replace(':', '').splitlines()):
  8. graph[aa] |= set(bbs)
  9. for bb in bbs:
  10. graph[bb] |= {aa}
  11. return graph
  12. def cut(graph, wires):
  13. graph = graph.copy()
  14. for aa, bb in wires:
  15. graph[aa] = graph[aa] - {bb}
  16. graph[bb] = graph[bb] - {aa}
  17. return graph
  18. def subgraphs(graph):
  19. conns = []
  20. while graph:
  21. state = {next(iter(graph))}
  22. seen = set()
  23. while state:
  24. state = {new for old in state for new in graph[old] if new not in seen}
  25. seen |= state
  26. conns.append(seen)
  27. for node in seen:
  28. graph.pop(node)
  29. return conns
  30. def shortest_path(graph, aa, bb):
  31. state = {aa: None}
  32. seen = {}
  33. while bb not in state:
  34. state = {new: old for old in state for new in graph[old] if new not in seen}
  35. seen |= state
  36. path = [bb]
  37. while path[-1] != aa:
  38. path.append(seen[path[-1]])
  39. return path
  40. def rank_wires(graph, n_cycles=100, n_top=20):
  41. tally = collections.Counter()
  42. for aa, bb in sorted(itertools.combinations(graph, 2))[:n_cycles]:
  43. path = shortest_path(graph, aa, bb)
  44. tally.update(frozenset(pair) for pair in zip(path, path[1:]))
  45. return [k for k, _ in tally.most_common(n_top)]
  46. text = open(0).read()
  47. graph = make_graph(text)
  48. for triplet in itertools.combinations(rank_wires(graph), 3):
  49. mod_graph = cut(graph, triplet)
  50. subs = subgraphs(mod_graph)
  51. if len(subs) == 2:
  52. print(len(subs[0]) * len(subs[1]))
  53. break