"""
KM算法
复杂度O(E*V*V)?
"""
a =-float('inf')# a = 5
graph =[[4,2,6, a, a],[2,6, a,6,3],[a,3,6, a, a],[a,8,2, a, a],[a, a, a,3,1]]
label_left, label_right =[max(g)for g in graph],[0for _ in graph]
S, T ={},{}
visited_left =[Falsefor _ in graph]
visited_right =[Falsefor _ in graph]
slack_right =[float('inf')for _ in graph]deffind_path(i, visited_left, visited_right, slack_right):
visited_left[i]=Truefor j, match_weight inenumerate(graph[i]):if visited_right[j]:continue
gap = label_left[i]+ label_right[j]- match_weight
if gap ==0:
visited_right[j]=Trueif j notin T or find_path(T[j], visited_left, visited_right, slack_right):
T[j]= i
S[i]= j
returnTrueelse:
slack_right[j]=min(slack_right[j], gap)returnFalsedefKM():
m =len(graph)for i inrange(m):# 重置辅助变量
slack_right =[float('inf')for _ inrange(m)]whileTrue:
visited_left =[Falsefor _ in graph]
visited_right =[Falsefor _ in graph]if find_path(i,visited_left,visited_right, slack_right):break
d =float('inf')for j, slack inenumerate(slack_right):ifnot visited_right[j]and slack < d:
d = slack
for k inrange(m):if visited_left[k]:
label_left[k]-= d
if visited_right[k]:
label_right[k]+= d
return S, T
KM()print(S)