题目描述
有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为 c[i][j] 。试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。
输入格式:
文件的第 1 行有 1 个正整数 n,表示有 n 件工作要分配给 n个人做。
接下来的n 行中,每行有 n 个整数 c[i][j],表示第 i个人做第 j 件工作产生的效益为 c[i][j]。
输出格式:
两行分别输出最小总效益和最大总效益。
求最小总效益就是经典的指派问题,最大总收益只要把c乘-1再求最小就可以。
这里举个例子
n = 5,c为下表
12 | 7 | 9 | 7 | 9 |
---|---|---|---|---|
8 | 9 | 6 | 6 | 6 |
7 | 17 | 12 | 14 | 9 |
15 | 14 | 6 | 6 | 10 |
4 | 10 | 7 | 10 | 9 |
第一步:每行减去该行最小的数,保证每行都有0。
5 | 0 | 2 | 0 | 2 |
---|---|---|---|---|
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
第二步:每列减去该列最小的数,保证每行每列都有0。
5 | 0 | 2 | 0 | 2 |
---|---|---|---|---|
2 | 3 | 0 | 0 | 0 |
0 | 10 | 5 | 7 | 2 |
9 | 8 | 0 | 0 | 4 |
0 | 6 | 3 | 6 | 5 |
第三步:
从单个0元素的行开始,给0加圈,记作O,然后划去所在行的其它0元素,记为X。
第四步:
从单个0元素的列开始,给0加圈,记作O,然后划去所在列的其它0元素,记为X。
重复三四,直到无法标记;
第五步:
若还存在没有画圈的0元素,则从剩余的0元素最少的行(列)开始,选0元素画圈,然后划掉同行同列的其它0元素,反复进行,直到所有0元素均被圈出或划掉为止;
检验:
若O的数目cnt=n,则该指派问题的最优解已经得到。
否则,进行调整。
5 | O | 2 | X | 2 |
---|---|---|---|---|
2 | 3 | X | X | O |
O | 10 | 5 | 7 | 2 |
9 | 8 | O | X | 4 |
X | 6 | 3 | 6 | 5 |
例子cnt = 4,少一个O
调整:找最少覆盖所有0的直线
- 对没有O的行打√
- 对已打√行中含X所在列打√
- 对已打√列中含O所在行打√
- 重复2~3, 直至没有要打√的行和列为止
- 对没有打√的行划横线, 对打√的列划竖线,得到最少覆盖所有0的直线。
- 取未划线的最小数,未划线的减去这个数,线交点处加上这个数。
返回第一步。
打√后
5 | O | 2 | X | 2 | |
---|---|---|---|---|---|
2 | 3 | X | X | O | |
O | 10 | 5 | 7 | 2 | √3 |
9 | 8 | O | X | 4 | |
X | 6 | 3 | 6 | 5 | √1 |
√2 |
调整6后
7 | 0 | 2 | 0 | 2 |
---|---|---|---|---|
4 | 3 | 0 | 0 | 0 |
0 | 8 | 3 | 5 | 0 |
11 | 8 | 0 | 0 | 4 |
0 | 4 | 1 | 4 | 3 |
正确性初步说明:同一行或同一列减去同一个数不影响最优分配方案
程序的一点说明:实际计算中, 第五步其实不需要dfs所有情况,模拟即可。相应调整5后可以这样: 设直线数为l,若l小于n,则转调整6;若l=n,则转第五步重新试探。程序直接枚举到最好的情况了,所以省了这个判断。
————————————————版权声明:本文为CSDN博主「QASWINE」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33831360/article/details/94043097
————————————————