inf, _inf = float("inf"), float('-inf') defkm(): defdfs(x): visx[x] = 1 for i inrange(1,H+1): ifnot visy[i] and lx[x] + ly[i] == g[x][i]: #两顶标相加等于边权为有效边 visy[i] = 1 if link[i] == 0or dfs(link[i]): link[i] = x return1 return0 for i inrange(1,P+1): whileTrue: visx,visy = [0]*(P+1), [0]*(H+1) if dfs(i): break d = inf for j inrange(1,P+1): if visx[j]: for k inrange(1,H+1): ifnot visy[k]: d = min(d, lx[j] + ly[k] - g[j][k]) if d == inf: return0 for j inrange(1,P+1): if visx[j]: lx[j] -= d for j inrange(1,H+1): if visy[j]: ly[j] += d return1
"""P为人的数量,H为房子的数量,人和房子分别为左右集合""" lx,ly,link = [_inf]*(P+1),[0]*(H+1),[0]*(P+1) for i inrange(1,P+1): for j inrange(1,H+1): if g[i][j] != 0: lx[i] = max(lx[i], g[i][j]) if km() == 1: ans = 0 for i inrange(1,H+1): ans += g[link[i]][i] #link记录了每个房子(右集合)匹配到的人的下标(左集合) print(-ans) #题目求的是最小匹配,我们将边取负,求最大匹配,输出相反数