km演算法用來求二分圖最大權完美匹配。
本文配合該博文服用更佳:趣寫演算法系列之--匈牙利演算法
現在有n男n女,有些男生和女生之間互相有好感,我們將其好感程度定義為好感度,我們希望把他們兩兩配對,並且最後希望好感度和最大。
怎麼選擇最優的配對方法呢?
首先,每個女生會有乙個期望值,就是與她有好感度的男生中最大的好感度。男生呢,期望值為0,就是……只要有乙個妹子就可以啦,不挑~~
這樣,我們把每個人的期望值標出來。
接下來,開始配對。
配對方法:
我們從第乙個女生開始,分別為每乙個女生找物件。
每次都從第乙個男生開始,選擇乙個男生,使男女兩人的期望和要等於兩人之間的好感度。
注意:每一輪匹配,每個男生只會被嘗試匹配一次!
具體匹配過程:
**********====為女1找物件***************
(此時無人配對成功)
根據 「男女兩人的期望和要等於兩人之間的好感度」的規則
女1-男1:4+0 != 3
女1-男3:4+0 == 4
所以女1選擇了男3
女1找物件成功
**********====為女1找物件成功**********==
**********====為女2找物件***************
(此時女1—男3)
根據配對原則,女2選擇男3
男3有主女1,女1嘗試換人
我們嘗試讓女1去找別人
嘗試失敗
為女2找物件失敗!
**********====為女2找物件失敗**********==
這一輪參與匹配的人有:女1,女2,男3。
怎麼辦???很容易想到的,這兩個女生只能降低一下期望值了,降低多少呢?
任意乙個參與匹配女生能換到任意乙個這輪沒有被選擇過的男生所需要降低的最小值
比如:女1選擇男1,期望值要降低1。 女2選擇男1,期望值要降低1。 女2選擇男2,期望值要降低2。
於是,只要期望值降低1,就有妹子可能選擇其他人。所以妹子們的期望值要降低1點。
同時,剛才被搶的男生此時非常得意,因為有妹子來搶他,於是他的期望值提高了1點(就是同妹子們降低的期望值相同)。
於是期望值變成這樣(當然,不參與剛才匹配過程的人期望值不變)
**********====繼續為女2找物件**********===
(此時女1—男3)
女2選擇了男1
男1還沒有被配對
女2找物件成功!
**********====為女2找物件成功**********===
**********====為女3找物件***************
(此時女1—男3,女2-男1)
女3沒有可以配對的男生……
女3找物件失敗
**********====為女3找物件失敗**********==
此輪只有女3參與匹配
此時應該為女3降低期望值
降低期望值1的時候,女3-男3可以配對,所以女3降低期望值1
**********====繼續為女3找物件**********==
(此時女1—男3, 女2-男1)
女3相中了男3
此時男3已經有主女1,於是女1嘗試換人
女1選擇男1
而男1也已經有主女2,女2嘗試換人
前面說過,每一輪匹配每個男生只被匹配一次
所以女2換人失敗
女3找物件再次失敗
**********====為女3找物件失敗**********==
此時,只要女2降低1點期望值,就能換到男2
(前面提過 只要任意乙個女生能換到任意乙個沒有被選擇過的男生所需要降低的最小值)
我們把相應人員期望值改變一下
**********====還是為女3找物件**********==
(此時女1—男3, 女2-男1)
女3選擇了男3
男3有主女1,女1嘗試換人
女1換到了男1
男1已經有主女2,女2嘗試換人
女2換人男2
男2無主,匹配成功!!!
**********====為女3找物件成功**********===
匹配成功!!!撒花~~
到此匹配全部結束
此時女1-男1,女2-男2,女3-男3
好感度和為最大:9
雖然不停換人的過程聽起來很麻煩,但其實整個是個遞迴的過程,實現起來比較簡單。比較複雜的部分就是期望值的改變,但是可以在遞迴匹配的過程中順帶求出來。
模板(帶詳細注釋)(入門題:hdu2255(複雜度應該是o(n^3)
#include
#include
#include
using
namespace std;
const
int maxn =
305;
const
int inf =
0x3f3f3f3f
;int love[maxn]
[maxn]
;// 記錄每個妹子和每個男生的好感度
int ex_girl[maxn]
;// 每個妹子的期望值
int ex_boy[maxn]
;// 每個男生的期望值
bool vis_girl[maxn]
;// 記錄每一輪匹配匹配過的女生
bool vis_boy[maxn]
;// 記錄每一輪匹配匹配過的男生
int match[maxn]
;// 記錄每個男生匹配到的妹子 如果沒有則為-1
int slack[maxn]
;// 記錄每個漢子如果能被妹子傾心最少還需要多少期望值
int n;
bool
dfs(
int girl)
}else
}return
false;}
intkm()
}// 嘗試為每乙個女生解決歸宿問題
for(
int i =
0; i < n;
++i)}}
// 匹配完成 求出所有配對的好感度的和
int res =0;
for(
int i =
0; i < n;
++i)
res +
= love[ match[i]
][i]
;return res;
}int
main()
return0;
}
KM演算法 詳解 模板
km演算法及其具體過程 1 可行點標 每個點有乙個標號,記lx i 為x方點i的標號,ly j 為y方點j的標號。如果對於圖中的任意邊 i,j,w 都有lx i ly j w,則這一組點標是可行的。特別地,對於lx i ly j w的邊 i,j,w 稱為可行邊 2 km 演算法的核心思想就是通過修改...
KM演算法 詳解 模板
先說km演算法求二分圖的最佳匹配思想,再詳講km的實現。km演算法求二分圖的最佳匹配思想 對於具有二部劃分 v1,v2 的加權完全二分圖,其中 v1 v2 邊 xi,yj 具有權值 wi,j 該帶權二分圖中乙個總權值最大的完美匹配,稱之為最佳匹配。記 l x 表示結點 x 的標記量,如果對於二部圖中...
KM演算法模板
這是hdu2255 include include include include includeusing namespace std const int maxn 305 const int inf 0x3f3f3f3f int love maxn maxn 記錄每個妹子和每個男生的好感度 in...