from collections import deque
def main():
operations = []
def emit(op, v1, v2):
operations.append((op, v1, v2))
n = int(input())
if n == 2:
print(0)
return
m = int(input())
graph = {i: set() for i in range(1, n + 1)}
edges = set()
for _ in range(m):
edge = input().split()
v1, v2 = int(edge[0]), int(edge[1])
graph[v1].add(v2)
graph[v2].add(v1)
edges.add((min(v1, v2), max(v1, v2)))
dst_m = int(input())
dst_graph = {i: set() for i in range(1, n + 1)}
dst_edges = set()
for _ in range(dst_m):
edge = input().split()
v1, v2 = int(edge[0]), int(edge[1])
dst_graph[v1].add(v2)
dst_graph[v2].add(v1)
dst_edges.add((min(v1, v2), max(v1, v2)))
# len_ = len(edges.intersection(dst_edges))
# print(f"{len_=}")
# phase 1: Connect all nodes directly to 1st node using BFS traversal
visited = set()
visited.add(1)
queue = deque()
for neigh in graph[1]:
queue.append(neigh)
visited.add(neigh)
while queue:
for _ in range(len(queue)):
v = queue.popleft()
for neigh in graph[v]:
if neigh in visited:
continue
emit("+", 1, neigh)
queue.append(neigh)
visited.add(neigh)
edges.add((1, neigh))
# phase 2: remove/add edges between any two nodes a and b such a != 1 and b != 1 to be as in dst graph
# We can do that since any two nodes are connect via node 1
to_add = dst_edges - edges
for v1, v2 in to_add:
if v1 == 1:
# such edge already been added in 1st phase
continue
emit("+", v1, v2)
to_remove = edges - dst_edges
to_remove_1st_node = set()
for v1, v2 in to_remove:
if v1 == 1:
# those edges will be removed in 3rd phase
to_remove_1st_node.add(v2)
else:
emit("-", v1, v2)
# print(edges)
# print(dst_edges)
# print(to_add)
# print(to_remove)
# print(to_remove_1st_node)
# phase 3: remove unnecessary edges from node 1 using DFS
visited = set()
visited.add(1)
stack = [1]
order = []
while stack:
# print(stack)
v = stack.pop()
order.append(v)
for neigh in dst_graph[v]:
if neigh in visited:
continue
visited.add(neigh)
stack.append(neigh)
# print(order)
for v in reversed(order):
if v in to_remove_1st_node:
emit("-", 1, v)
# def dfs(v):
# # print(f"dfs {v}")
# visited.add(v)
# for neigh in dst_graph[v]:
# if neigh in visited:
# continue
# dfs(neigh)
# if v in to_remove_1st_node:
# emit("-", 1, v)
#
# dfs(1)
print(len(operations))
for op, v1, v2 in operations:
print(f"{op} {v1} {v2}")
if __name__ == "__main__":
main()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | from collections import deque def main(): operations = [] def emit(op, v1, v2): operations.append((op, v1, v2)) n = int(input()) if n == 2: print(0) return m = int(input()) graph = {i: set() for i in range(1, n + 1)} edges = set() for _ in range(m): edge = input().split() v1, v2 = int(edge[0]), int(edge[1]) graph[v1].add(v2) graph[v2].add(v1) edges.add((min(v1, v2), max(v1, v2))) dst_m = int(input()) dst_graph = {i: set() for i in range(1, n + 1)} dst_edges = set() for _ in range(dst_m): edge = input().split() v1, v2 = int(edge[0]), int(edge[1]) dst_graph[v1].add(v2) dst_graph[v2].add(v1) dst_edges.add((min(v1, v2), max(v1, v2))) # len_ = len(edges.intersection(dst_edges)) # print(f"{len_=}") # phase 1: Connect all nodes directly to 1st node using BFS traversal visited = set() visited.add(1) queue = deque() for neigh in graph[1]: queue.append(neigh) visited.add(neigh) while queue: for _ in range(len(queue)): v = queue.popleft() for neigh in graph[v]: if neigh in visited: continue emit("+", 1, neigh) queue.append(neigh) visited.add(neigh) edges.add((1, neigh)) # phase 2: remove/add edges between any two nodes a and b such a != 1 and b != 1 to be as in dst graph # We can do that since any two nodes are connect via node 1 to_add = dst_edges - edges for v1, v2 in to_add: if v1 == 1: # such edge already been added in 1st phase continue emit("+", v1, v2) to_remove = edges - dst_edges to_remove_1st_node = set() for v1, v2 in to_remove: if v1 == 1: # those edges will be removed in 3rd phase to_remove_1st_node.add(v2) else: emit("-", v1, v2) # print(edges) # print(dst_edges) # print(to_add) # print(to_remove) # print(to_remove_1st_node) # phase 3: remove unnecessary edges from node 1 using DFS visited = set() visited.add(1) stack = [1] order = [] while stack: # print(stack) v = stack.pop() order.append(v) for neigh in dst_graph[v]: if neigh in visited: continue visited.add(neigh) stack.append(neigh) # print(order) for v in reversed(order): if v in to_remove_1st_node: emit("-", 1, v) # def dfs(v): # # print(f"dfs {v}") # visited.add(v) # for neigh in dst_graph[v]: # if neigh in visited: # continue # dfs(neigh) # if v in to_remove_1st_node: # emit("-", 1, v) # # dfs(1) print(len(operations)) for op, v1, v2 in operations: print(f"{op} {v1} {v2}") if __name__ == "__main__": main() |
English