KM演算法萌新講解篇

2021-07-23 08:21:39 字數 1854 閱讀 6679

km演算法

首先了解問題:也就是最大權值匹配;

二分圖里,邊帶了權值,求整幅圖里匹配最大/最小的權值

因為接觸匈牙利演算法的時候看的是找物件系列的博文,所以也自己寫一發找物件的博文吧;

演算法背景:

資訊學院計算機某班級有5位玉樹凌風的男子:小諸,小包,小許,小應,小章;

外語學院英語系某班級有5位國色天香的女子:小四,小雨,小美,小麗,小英;

名稱不重要!強行變成x,y,233333

然後5位男子對5位女子都有乙個好感度,見表;

現在要給這幾個男孩子找女朋友~使得他們所有好感度和最大。

km演算法步驟:

初始情況下把好感度都放在男子的集合上,即

然後列舉x集合元素去匹配,如果匹配到的邊wij=lxi+lyj,並且j還不存在配偶,那麼,嘿嘿嘿,就讓他們牽手~(✿◡‿◡)

比如:在列舉x集合時,x0-y2;x1-y3;x2-y4;

但是,有些女孩子很受歡迎,突然到了x3,x3最喜歡y2,而y2已經有x0喜歡了,窩們的目的是讓整個好感度最大;

那麼就會有兩種情況:

①  :我讓x0再去找乙個,然後讓x3-y2;

②  :我讓x3另外去選,然後還是讓x0-y2;

那麼窩們怎麼能隨隨便便讓男孩子另外去找乙個呢,窩們其實很容易想到乙個方案就是讓乙個男孩子去找另外乙個女孩子使得好感度比原先大的好感度降低的越少,那麼這樣還是會讓總好感度最大;

具體的方法就是窩們可以開乙個差值陣列代表最大的好感度和其他好感度的差;

然後每次在尋找女朋友的時候將這個差值陣列進行更新;

每次掃完女孩子以後,如果沒有找到心儀物件,

找到那個最小差值d

把lx陣列種那些有矛盾的男孩子的值-=d;

把ly陣列種那些引起矛盾的女孩的值+=d;

觀察窩們說乙個男孩子找到女朋友的條件是:如果匹配到的邊wij=lxi+lyj,並且j還不存在配偶,那麼,嘿嘿嘿,就讓他們牽手~(✿◡‿◡)

這樣就能保證在下次找配偶的過程中

1.lx-=d,當再次對當前有矛盾的男孩子尋找時可能一下子找到那個好感度減少最少的女孩,因為lx減少,然而ly不變,所以一旦滿足條件,就返回true;

2.ly+=d,引起矛盾的那個女生還是照樣引起矛盾或者在之前就被尋找過在下次尋找到時不尋找;

3.在對出現矛盾的那個女生的本來配好的男朋友進行尋找時,同理1的情況,找到那個好感度減少最少的女孩且滿足情況就返回;

這樣演算法流程說明(個人理解):

lx的作用是維護權值減少最少,ly的作用是維護權值最大的依舊最大;

教科書術語:

(1)  令(u,v)是乙個覆蓋,如對於每個j,ui=max(wij),vi=0;

(2)  在ku*v中找出乙個最大匹配m。如果m是乙個完美匹配,停止並將m作為最大權值匹配返回。否則,令q是ku*v中大小為m的乙個定點覆蓋。設r=q∩x,t=q∩y。令e=min{ui+vj-wij,xi∈x-r,yi∈y-t}。

(3)  對於xi∈x-r,從ui中減去e.對yi∈t,把e加到vj上,形成乙個新的相等子圖,轉向步驟(2);

貼一發模板:

bool findpath(int u)

}else if(d>temp)

d=temp;

}return false;

}int km()}}

int res=0;

for(int i=1;i<=n;i++)

return res;

}

單調棧萌新講解

單調棧 哈。怎麼開始介紹這個單調棧是乙個小問題。所以就直接講他的功能了 在入棧時遵循單調原則,可以求出乙個元素向左和向右所能擴充套件的最大長度 具體操作 例1 求乙個元素的右側的最近比他大的元素位置 bzoj3401 input 輸入乙個n代表元素個數,輸入n個元素 63 2 6 1 1 2 out...

KM演算法趣味講解 模板

本文 同時也參考了 本文配合該博文服用更佳 趣寫演算法系列之 匈牙利演算法 km演算法用來求二分圖最大權完美匹配。km演算法的思路 盡量找最大的邊進行連邊,如果不能則換一條較大的。現在有n男n女,男生和女生每兩個人之間有好感度,我們希望把他們兩兩配對,並且最後希望好感度和最大。怎麼選擇最優的配對方法...

萌新的資料結構與演算法3 A 演算法

astar是一種深度優先啟發式尋路演算法,廣泛運用在遊戲領域。提起astar不得不提一下迪傑特斯拉演算法,它是一種廣度優先啟發式尋路演算法,俗稱閹割版的astar。因為大部分情況下astar的效率都比迪傑特斯拉高,我們只需要稍作了解就可以。astar的原理,有一篇部落格寫的很詳細,萌新推薦一下 pu...