匈牙利 算法&模板


匈牙利 算法

一. 算法簡介

匈牙利算法是由匈牙利數學家Edmonds於1965年提出。該算法的核心就是尋找增廣路徑,它是一種用增廣路徑求二分圖最大匹配的算法。

二分圖的定義:

設G=(V,E)是一個無向圖,頂點集V可分割為兩個互不相交的子集V1,V2,那么稱此圖G為二分圖。

例如,下圖就是一個二分圖:

二分圖的匹配:

二分圖中的子圖中,每個節點只連一條邊,則稱該子圖是二分圖中的一個匹配。

 

極大匹配:

無法再向二分圖中加入邊,使得滿足匹配條件。

 

最大匹配:

所有極大匹配中邊數最多的一個匹配。

 

完美匹配

如果一個圖的某個匹配中,所有的頂點都是匹配點,那么它就是一個完美匹配。

 

方法:

求最大匹配的一種顯而易見的算法是:先找出全部匹配,然后保留匹配數最多的。但是這個算法的時間復雜度為邊數的指數級。因此,需要尋求一種更加高效的算法。下面介紹用增廣路求最大匹配的方法。

 

算法圖解:

下圖是一個二分圖,現在求最大匹配。

先從1出發,找增廣路,找到1->A 這條路,標記並記錄。

從2出發,找到2->B這條路,標記並記錄。

從3開始找,發現3所連接邊全部被占用,這時進行一個神奇的操作:

從三開始找一條增廣路,3 -> A -> 1 -> B -> 2 -> C 

這時,在圖中將有兩種顏色的邊刪去,留下綠色的邊。

這時,這張圖的最大匹配值就是3.

 

三.算法模板

 核心代碼:

 1 bool Hungary ( int x ) {
 2          for ( int i = head[ x ] ; i ; i = E[ i ] . next ) {
 3                  if ( vis[ i ] ) continue ;
 4                  int temp = E[ i ] . to ; 
 5                  vis[ i ] = true ;
 6                  if ( !match[ temp ] || Hungary ( match[ temp ] ) ) {
 7                           match [ temp ] = x ;
 8                           return true ;
 9                  }
10          }
11          return false ;
12 } 

主程序:

for ( k=1 ; k<=M ; ++k ) {
                 memset ( vis , false , sizeof ( vis ) ) ; 
                 if ( !Hungary ( k ) )
                         break ; 
}

 

時間復雜度:
鄰接矩陣:  O(n3)
鄰接表: O(nm)
 
空間復雜度:
鄰接矩陣:  O(n2)
鄰接表:O(n+m)

2016-09-16 02:18:44

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM