Now flights and cargo orders arrive over time. Implement a streaming planner that supports updates and answers the current maximum profit after each query. Use the same shipment model as Part 1: each active flight can carry at most one active cargo, a cargo can use a flight only if departure_time <= latest_arrival and max_weight >= weight, and the profit of matching a cargo to a flight is revenue - cost. For this platform, implement a function that processes operations and returns the answer for every QUERY operation. Re-adding an existing id replaces the previous active record with that id. Removing a non-existent id should do nothing.
Examples
Input: [('ADD_FLIGHT', 'F1', 1, 10, 100), ('ADD_CARGO', 'C1', 4, 3, 90), ('QUERY',), ('ADD_CARGO', 'C2', 6, 5, 140), ('QUERY',), ('ADD_FLIGHT', 'F2', 3, 5, 30), ('QUERY',)]
Expected Output: [0, 40, 100]
Explanation: With only F1 and C1, shipping loses money so the best profit is 0. After adding C2, F1 can profitably ship it for 40. After adding F2, the best matching becomes 100.
Input: [('ADD_FLIGHT', 'F1', 1, 5, 5), ('ADD_FLIGHT', 'F2', 2, 10, 20), ('ADD_CARGO', 'C1', 5, 2, 40), ('ADD_CARGO', 'C2', 10, 2, 50), ('QUERY',), ('REMOVE_CARGO', 'C2'), ('QUERY',), ('REMOVE_FLIGHT', 'F1'), ('QUERY',)]
Expected Output: [65, 35, 20]
Explanation: The best matching first uses both flights. After removing C2, only C1 remains and F1 is the better choice. After removing F1, only F2 can ship C1.
Input: [('QUERY',)]
Expected Output: [0]
Explanation: Querying an empty system should return 0.
Input: [('ADD_FLIGHT', 'F1', 5, 5, 10), ('ADD_CARGO', 'C1', 5, 4, 100), ('QUERY',), ('ADD_FLIGHT', 'F1', 3, 5, 10), ('QUERY',), ('REMOVE_CARGO', 'NOPE'), ('REMOVE_FLIGHT', 'F1'), ('QUERY',)]
Expected Output: [0, 90, 0]
Explanation: The first version of F1 is too late for C1, then re-adding F1 replaces it with a feasible version. Removing a non-existent cargo is ignored.
Solution
def solution(operations):
def max_profit(flights, cargos):
n_f = len(flights)
n_c = len(cargos)
n = max(n_f, n_c)
if n == 0:
return 0
profit = [[0] * n for _ in range(n)]
max_cell = 0
for i, (depart, max_weight, cost) in enumerate(flights):
for j, (weight, latest_arrival, revenue) in enumerate(cargos):
if depart <= latest_arrival and max_weight >= weight:
value = revenue - cost
if value > 0:
profit[i][j] = value
if value > max_cell:
max_cell = value
cost_matrix = [[max_cell - profit[i][j] for j in range(n)] for i in range(n)]
u = [0] * (n + 1)
v = [0] * (n + 1)
p = [0] * (n + 1)
way = [0] * (n + 1)
for i in range(1, n + 1):
p[0] = i
j0 = 0
minv = [float('inf')] * (n + 1)
used = [False] * (n + 1)
while True:
used[j0] = True
i0 = p[j0]
delta = float('inf')
j1 = 0
for j in range(1, n + 1):
if not used[j]:
cur = cost_matrix[i0 - 1][j - 1] - u[i0] - v[j]
if cur < minv[j]:
minv[j] = cur
way[j] = j0
if minv[j] < delta:
delta = minv[j]
j1 = j
for j in range(n + 1):
if used[j]:
u[p[j]] += delta
v[j] -= delta
else:
minv[j] -= delta
j0 = j1
if p[j0] == 0:
break
while True:
j1 = way[j0]
p[j0] = p[j1]
j0 = j1
if j0 == 0:
break
assignment = [-1] * n
for j in range(1, n + 1):
if p[j] != 0:
assignment[p[j] - 1] = j - 1
answer = 0
for i in range(n_f):
j = assignment[i]
if 0 <= j < n_c:
answer += profit[i][j]
return answer
active_flights = {}
active_cargos = {}
answers = []
for op in operations:
kind = op[0]
if kind == 'ADD_FLIGHT':
_, flight_id, depart, max_weight, cost = op
active_flights[flight_id] = (depart, max_weight, cost)
elif kind == 'ADD_CARGO':
_, cargo_id, weight, latest_arrival, revenue = op
active_cargos[cargo_id] = (weight, latest_arrival, revenue)
elif kind == 'REMOVE_FLIGHT':
_, flight_id = op
active_flights.pop(flight_id, None)
elif kind == 'REMOVE_CARGO':
_, cargo_id = op
active_cargos.pop(cargo_id, None)
elif kind == 'QUERY':
answers.append(max_profit(list(active_flights.values()), list(active_cargos.values())))
else:
raise ValueError('Unknown operation: ' + str(kind))
return answersTime complexity: O(Q * (A^3 + F * C)) in the worst case, where Q is the number of QUERY operations, A is max(active flights, active cargos) at that query, and F and C are the active counts. Space complexity: O(A^2).