给定一个位数组,如下所示:
C0 C1 C2 C3 C4 C5
**********************************************
P0 * 0 0 1 0 1 0 *
P1 * 0 1 0 0 1 0 *
P2 * 0 0 0 1 1 0 *
P3 * 1 0 0 0 0 1 *
P4 * 0 0 0 0 0 0 *
P5 * 0 0 0 0 0 0 *
P6 * 1 0 0 0 0 0 *
**********************************************
每行代表不同的人 P_i,而每列代表不同的颜色 C_j。如果给定的单元格 A[i][j] 为 1,则表示我想要颜色 j。一个人只能得到一种颜色,一种颜色只能给一个人。
一般来说,人数P>=0,颜色数C>=0。
我怎样才能高效地计算出能够获得所需颜色的最大人数?
上面例子的正确答案是 5。
- 人 6 (P6) 只有一个愿望,所以他得到颜色 0 (C0)
- 由于现在取C0,P3只剩下一个愿望,所以他得到C5。
- P0 得到 C2,P1 得到 C1,P2 得到 C3。
我的第一个想法是贪婪的 algorithm,它只是偏爱所需颜色数量最少的人(即行)。这在大多数情况下都有效,但对我来说太慢了,因为它在 O(P*(P*C)) 时间内运行,当 n = P = C 时等于 O(n^3)。任何可以更快地解决问题的 algorithm (或其他数据结构)的想法?
这可能是另一个类似问题的重复,但我在找到问题类型的正确名称时遇到了麻烦,如果是这种情况,请多多包涵。
回答1
这是一个被称为最大基数二分匹配的经典问题。在这里,您有一个二分图,其中一侧的顶点对应于人,另一侧的顶点对应于颜色。如果矩阵的相应条目中有一条边,则存在人和颜色之间的边。
在一般情况下,最知名的 algorithms 的最差情况性能为 O(E*sqrt(V)),其中 E 是图中的边数,V 是顶点数。一个这样的 algorithm 称为 https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm。我建议您阅读我链接的维基百科解释。