演算法學習之路|二分圖的最大匹配—匈牙利演算法(Dfs實現)

kissjz發表於2018-02-24

二分圖的概念:二分圖又稱作二部圖,是圖論中的一種特殊模型。 設G=(V,E)是一個無向圖,如果頂點V可分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A,j in B),則稱圖G為一個二分圖。

匹配:在圖論中,一個匹配是一個邊的集合,其中任意兩條邊都沒有公共頂點。

最大匹配:一個圖所有匹配中,所含匹配邊數最多的匹配,稱為這個圖的最大匹配。

交替路:從一個未匹配點出發,依次經過非匹配邊、匹配邊、非匹配邊…形成的路徑叫交替路。

增廣路:從一個未匹配點出發,走交替路,如果途徑另一個未匹配點,則這條交替路稱為增廣路。

增廣路有個重要特點就是:未匹配邊數比匹配邊數多一,這樣就可以讓未匹配邊和匹配邊身份交換使得匹配邊數加一,所以一直尋找增廣路來增加匹配數,直到找不到增光路為止。

程式碼實現(Dfs):

struct Edge
{
    int from;
    int to;
};
vector <int> G[max];//儲存i點的出發點編號
int matchingnode[max];
int check[max];
int Dfs(int u)
{
    vector <int>::iterator it;
    for(it=G[u].begin();it!=G[u].end();it++)
    {
        int v=*it;
        if(!check[v])//判斷是否在交替路中
        {
            check[v]=1;
            if(matchingnode[v]==-1||Dfs(matchingnode[v]))//是否是匹配點
            {
                matching[v]=u;
                matching[u]=v;
                return 1;
            }
        }
    }
    return 0;
}
int hungarian ()
{
    int _count;
    memset(matchingnode,-1,sizeof(matchingnode));
    for(int i=0;i<max;i++)
    {
        if(matchingnode[i]==-1)
        {
            memset(check,0,sizeof(check));
            if(Dfs(i))
                _count++;
        }
    }
    return _count;
}


相關文章