二分匹配總結


二分匹配總結

         首先講一下什么是二分圖,在一個圖中,以邊為條件,能將兩個端點划分為兩個集合的圖叫做二分圖,如下圖:

 

       

左圖為二分圖,右圖為簡化后的二分圖。

   

    接着就是二分圖的匹配問題,二分圖的匹配就是找一個邊的集合,每條邊的的頂點的度數為1。

如上圖所示,匹配到四條邊。

    二分圖的完美匹配,就是所有的頂點都有匹配點,這樣的叫做完美匹配,上圖所示所有的點都有匹配點,所以可以成為完美匹配,並不是所有的圖都有完美匹配的。

 

 

講完了理論部分,那怎么樣實現二分圖的匹配問題吶,這里就引出了匈牙利算法,匈牙利算法的核心思想就是“能上就上,不能上創造條件也要上”

以下圖為例:

首先給1號同學找對象,找到了5號;

然后再給2號同學找對象,找到了5號,但是5號同學已經有對象了怎么辦吶,辦法了,只能讓5號先跟1號分手,重新給1號找對象,這時候一號的對象就換成了7號,而2號同學就和5號同學在一起了;

接下來就是給3號同學找對象了,找到了5號同學,但是5號同學已經有2號同學了,沒辦法了,先讓2號同學和五號同學分手,剛分手就發現,2號同學除了5號就找不到對象了,所以只能放棄,讓3號同學找下一個對象,這樣3號同學就找到了,6號同學。

最后就是給4號同學找對象,4號喜歡7號,唉…….這關系我都有點蒙了,多關注一下90后孤獨老人,年輕人關系這么復雜……沒辦法了讓7號先和1號分手吧,分手只有又發現問題了,1號又沒有對象了,所以還是不能分手,只能讓4號重新找對象了,這樣4號就找到了8號這樣,就完成了,這8個人的匹配問題……

通過代碼實現的時候就是利用dfs,給每個人找對象的時候先向上搜索看能不能創造條(fen)件(shou)來進行匹配,如果不能的話只能自己重新找對象了。

/***********************二分匹配模板**************************/
const int MAXN=1000;
int uN,vN;  //u,v數目
int g[MAXN][MAXN];//編號是0~n-1的
int linker[MAXN];//記錄匹配點i的匹配點是誰
bool used[MAXN];
bool dfs(int u)//回溯看能不能通過分手來進行匹配
{
    int v;
    for(v=0;v<vN;v++)
        if(g[u][v]&&!used[v])
                  //如果有這條邊,並且這條邊沒有用過
        {
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v]))//如果這個點沒有匹配過,並且能找到匹配點,那么就可以以這個邊作為匹配點
            {
                linker[v]=u;
                return true;
            }    
        }  
    return false;  
}    
int hungary()//返回最大匹配數
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))//如果這個點有匹配點
                          res++;
    } 
    return res;   
}
/***********************二分匹配模板**************************/

 

 


免責聲明!

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



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