-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwaif.py
More file actions
88 lines (75 loc) · 2.65 KB
/
waif.py
File metadata and controls
88 lines (75 loc) · 2.65 KB
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
from collections import defaultdict
class Graph:
def __init__(self, vertices):
self.V = vertices
self.graph = defaultdict(list)
self.capacities = {}
def addEdge(self, u, v, w=1):
self.graph[u].append(v)
self.graph[v].append(u) # for the back edges
self.capacities[(u, v)] = w
# Ensure the back edge exists in the capacities dictionary
if (v, u) not in self.capacities:
self.capacities[(v, u)] = 0
def BFS(self, s, t, parent):
visited = [False] * self.V
queue = []
queue.append(s)
visited[s] = True
while queue:
u = queue.pop(0)
for ind, val in enumerate(self.graph[u]):
if visited[val] == False and self.capacities[(u, val)] > 0:
queue.append(val)
visited[val] = True
parent[val] = u
return visited[t]
def fordFulkerson(self, source, sink):
parent = [-1] * self.V
max_flow = 0
while self.BFS(source, sink, parent):
path_flow = float("Inf")
s = sink
while s != source:
path_flow = min(path_flow, self.capacities[(parent[s], s)])
s = parent[s]
max_flow += path_flow
v = sink
while v != source:
u = parent[v]
self.capacities[(u, v)] -= path_flow
self.capacities[(v, u)] += path_flow
v = parent[v]
return max_flow
n_children, m_toys, p_cat = map(int, input().split())
V = n_children + m_toys + p_cat + 2
g = Graph(V)
source = 0
sink = V - 1
# Connect source to all children
for i in range(1, n_children + 1):
g.addEdge(source, i)
toy_start = n_children + 1
category_start = toy_start + m_toys
for i in range(1, n_children + 1):
toys = list(map(int, input().split()))[1:]
for toy in toys:
g.addEdge(i, toy_start + toy - 1)
toy_categories = {}
category_limits = {}
for i in range(p_cat):
line = list(map(int, input().split()))
toys_in_category = line[1:-1]
limit = line[-1]
category_node = category_start + i
category_limits[category_node] = limit
for toy in toys_in_category:
toy_categories[toy] = category_node
g.addEdge(toy_start + toy - 1, category_node)
g.capacities[(category_node, toy_start + toy - 1)] = 0 # No backflow from category to toy
g.addEdge(category_node, sink, limit)
# For toys not in a category, connect them directly to sink
for i in range(1, m_toys + 1):
if i not in toy_categories:
g.addEdge(toy_start + i - 1, sink)
print(g.fordFulkerson(source, sink))