題目描述
有 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
————————————————