def bfs(s, d, n, G, capacitate, flux):
coada = []
vis = [0] * (n + 1)
p = [0] * (n + 1)
coada.append(s)
vis[s] = 1
while len(coada) > 0:
nod = coada.pop(0)
for vecin in G[nod]:
if not vis[vecin] and capacitate[nod][vecin] - flux[nod][vecin] > 0:
vis[vecin] = 1
p[vecin] = nod
coada.append(vecin)
if vecin == d:
break
if not vis[d]:
return 0
path = []
x = d
while x != s:
path.append(x)
x = p[x]
path.append(s)
path.reverse()
flow_path = float('inf')
for i in range(len(path)-1):
u = path[i]
v = path[i+1]
flow_path = min(flow_path, capacitate[u][v] - flux[u][v])
for i in range(len(path) - 1):
u = path[i]
v = path[i + 1]
flux[u][v] += flow_path
flux[v][u] -= flow_path
return flow_path
def citire():
with open("cuplaj.in", 'r') as file:
lines = file.readlines()
N_L, M_R, E = map(int, lines[0].split())
total_nodes = N_L + M_R + 1
S = 0
D = total_nodes
capacitate = [{} for _ in range(total_nodes + 1)]
flux = [{} for _ in range(total_nodes + 1)]
G = [[] for _ in range(total_nodes + 1)]
def add_edge(u, v, cap):
G[u].append(v)
G[v].append(u)
capacitate[u][v] = cap
capacitate[v][u] = 0
flux[u][v] = 0
flux[v][u] = 0
for i in range(1, N_L + 1):
add_edge(S, i, 1)
for i in range(1, M_R + 1):
add_edge(N_L + i, D, 1)
for line in lines[1:]:
u, v = map(int, line.split())
add_edge(u, N_L + v, 1)
return total_nodes, S, D, N_L, M_R, G, capacitate, flux
def main():
n_total, S, D, N_L, M_R, G, capacitate, flux = citire()
max_flow = 0
while True:
flow_curent = bfs(S, D, n_total, G, capacitate, flux)
if flow_curent == 0:
break
max_flow += flow_curent
output_lines = []
output_lines.append(str(max_flow))
for u in range(1, N_L + 1):
for v_mapped in G[u]:
if v_mapped > N_L and v_mapped <= N_L + M_R:
if flux[u][v_mapped] == 1:
output_lines.append(f"{u} {v_mapped - N_L}")
with open('cuplaj.out', 'w') as file:
file.write('\n'.join(output_lines))
main()