Cod sursa(job #2960777)

Utilizator DariaClemClem Daria DariaClem Data 4 ianuarie 2023 22:27:00
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator py Status done
Runda Arhiva educationala Marime 2.61 kb
"""
    Complexitatea algoritmului este de O().
    Ideea algoritmului este
"""


# Algoritm clasic de bfs in care
import copy


def bfs():
    global visited, parent, flow
    visited = [0 for _ in range(2 * lCardinal + 2)]
    parent = [0 for _ in range(2 * lCardinal + 2)]

    visited[0] = 1
    parent[0] = -1
    order = [0]

    while order:
        currentNode = order.pop(0)

        for index in range(len(graph[currentNode])):
            neighbor = graph[currentNode][index]

            if not visited[neighbor] and capacity[currentNode][neighbor] > flow[currentNode][neighbor]:
                visited[neighbor] = 1
                parent[neighbor] = currentNode
                order.append(neighbor)

    return visited[final]


f = open("cuplaj.in", "r")
g = open("cuplaj.out", "w")

file = f.read().split('\n')

lCardinal, rCardinal, edges = [int(el) for el in file[0].split()]
graph = {key: [] for key in range(lCardinal + rCardinal + 2)}

start = 0
final = lCardinal + rCardinal + 1
capacity = [[0 for _ in range(lCardinal + rCardinal + 2)] for _ in range(lCardinal + rCardinal + 2)]
flow = copy.deepcopy(capacity)

for i in range(1, edges + 1):
    x, y = [int(el) for el in file[i].split()]
    y += lCardinal

    capacity[start][x] = capacity[y][final] = capacity[x][y] = 1

    graph[start].append(x)
    graph[x].append(start)

    graph[final].append(y)
    graph[y].append(final)

    graph[x].append(y)
    graph[y].append(x)

visited = [0 for _ in range(lCardinal + rCardinal + 2)]
parent = [0 for _ in range(lCardinal + rCardinal + 2)]

total = 0

while bfs():
    for i in range(len(graph[final])):
        if visited[graph[final][i]] and capacity[graph[final][i]][final] > flow[graph[final][i]][final]:
            node = graph[final][i]
            nextNode = final
            minim = capacity[node][nextNode] - flow[node][nextNode]

            while node >= 0:
                minim = min(minim, capacity[node][nextNode] - flow[node][nextNode])
                nextNode = node
                node = parent[node]

            if minim:
                node = graph[final][i]
                nextNode = final

                while node >= 0:
                    flow[node][nextNode] += minim
                    flow[nextNode][node] -= minim
                    nextNode = node
                    node = parent[node]

            total += minim

g.write(str(total) + '\n')

for i in range(lCardinal + 1):
    for j in range(lCardinal + 1, lCardinal + rCardinal + 1):
        if flow[i][j] == 1:
            g.write(f"{i} {j - lCardinal}\n")