7.二分圖匹配的匈牙利算法

先來講講什么是二分圖拘哨,一個圖的點如果可以被分成兩個集合米碰,并且任何一個邊的兩個端點都不在一個集合中补憾,那么這個圖就是二分圖

如圖
image.png

二分圖匹配的解決的又是什么問題叛拷?
現(xiàn)在有一些男生和一些女生在舞池聚會报亩,現(xiàn)在他們要跳舞浴鸿,每個人只愿意跟自己喜歡的異性跳舞,這個喜歡是相互的(即男喜歡此女弦追,此女必定也喜歡此男岳链,因為二分圖是無向圖),并且一個人只能跳一次舞劲件,現(xiàn)在告訴你他們互相的喜歡關(guān)系掸哑,問最多可以跳幾次舞蹈哈

前人的智慧總是無窮的,引用了一位洛谷大佬的題解來講一下匈牙利匹配零远,原題解
https://www.luogu.com.cn/problemnew/solution/P3386

匈牙利的本質(zhì)是協(xié)商或者說退讓苗分,讓我們來用圖看一下,下圖的連線表示喜歡關(guān)系


image.png

當兩個男生出現(xiàn)沖突(即兩個人選中同一個女生)牵辣,序號小的要考慮讓步去選序號大的女生摔癣,如果無法讓步(即沒有其他可選),則不退讓服猪。

可能有點抽象供填,不要緊,我們來看圖
每個人物代表一個點罢猪,連線代表可以處的cp(即可以進行的匹配)

開始匹配近她,毫無疑問男一匹配女一,沒有問題膳帕,已經(jīng)匹配的關(guān)系用藍色線表示


image.png

然后葉修來了粘捎,他也想要女一薇缅,這咋整,黃少看了一下攒磨,自己還可以選可愛的妹妹泳桦,他說那行,女一讓給你了娩缰,我要妹妹(女三)灸撰,于是圖變成了這樣


image.png

更麻煩的來了,張新杰也要女一拼坎,要跟葉修搶浮毯,葉修表示我還有初音,那女一就給你了泰鸡,然后圖是這樣的
image.png

本篇最慘男主登場债蓝,他也喜歡女一,他問男三能不能把女一讓給他啊盛龄,男三找了一下發(fā)現(xiàn)他沒有其他能選的饰迹,于是孫翔被拒絕了,本場單身狗誕生了余舶,匹配沒法進行下去了啊鸭,匈牙利算法結(jié)束!所以匹配數(shù)為3匿值!

觀察一下莉掂,本質(zhì)是讓步,只要出現(xiàn)沖突千扔,序號小的那個要考慮讓步,能讓就讓库正,如果不能讓步(即找不到其他妹子和自己配對)就拒絕讓步的要求曲楚,讓后面那個人不要和他搶,去找其他的女生褥符,如果后面這個人把自己喜歡的妹子都嘗試一遍都不行龙誊,那就單著吧

老規(guī)矩,結(jié)合題目看代碼喷楣,題目:https://www.luogu.com.cn/problem/P3386

image.png

這是個裸題趟大,我們直接建圖跑匈牙利算法(默認o1/就是成對輸入的第一個點那邊是左)
介紹兩個數(shù)組,parent數(shù)組铣焊,顧名思義逊朽,就是存右邊的點是跟誰匹配的,是已經(jīng)確定的匹配曲伊,par[3]=2代表左2和右3匹配叽讳,bool類型used數(shù)組則是代表嘗試匹配,或者說是被預(yù)定,used[2]=1代表右2被預(yù)定了岛蚤,在嘗試讓步的過程中不能嘗試2號點邑狸,hh這么說確實抽象,看代碼就明白了

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct xing
{
    int qian,wei;
}bian[1000010];
int n,m,e,u,v,parent[1010],cnt,head[1010],ans,used[1010];
void add(int o1,int o2)
{
    bian[++cnt].qian=head[o1];
    bian[cnt].wei=o2;
    head[o1]=cnt;
}
bool find(int u)
{
    for(int i=head[u];i;i=bian[i].qian)
    {//遍歷邊涤妒,就是挨個嘗試右邊的點能不能跟自己匹配
        int v=bian[i].wei;
        if(!used[v]){//如果沒有被預(yù)定
            used[v]=1;//那我就要了单雾,即使這個v點在之前已經(jīng)有配偶了,即par[v]不為0她紫,那我也要了硅堆,本來和這個v點匹配的左邊的點嘗試讓步
            if(parent[v]==0||find(parent[v]))//兩種情況,第一種情況:如果par[v]為0說明在之前還沒有人和v點確定匹配關(guān)系犁苏,那我就直接要了硬萍,第二種情況:如果已經(jīng)有人和v匹配了,那么就請par[v]去試試能不能換個人匹配围详,把v點讓給我朴乖,如果可以,那v這個點我也要了(是不是和之前的匹配圖對上了)
            {
                parent[v]=u;//確定匹配關(guān)系
                return 1;//返回真值助赞,意思是這個傳入?yún)?shù)u點匹配上了
            }
        }
    }
    return 0;//如果遍歷所有的邊這個u點都沒匹配上买羞,不管是因為他根本沒有喜歡的人還是他喜歡的人都被占了同時還沒有讓步給他,反正他是單著了(無遞歸)或者返回給之前讓u點嘗試讓步的點一個不能讓步的信息(遞歸進去了)
}
int main()
{
    int o1,o2;
    cin>>n>>m>>e;//一邊有n個點雹食,另外一邊有m個點畜普,一共有e個關(guān)系
    while(e--){//根據(jù)輸入的關(guān)系建邊
    cin>>o1>>o2;
    if(o1>n||o2>m)//如果輸入不合法,忽略他
    continue;
    add(o1,o2);//這里為了方便群叶,其實是用的單向邊吃挑,因為沒有必要雙向,之前說喜歡關(guān)系是相互的是方便理解街立,但是跑算法只需要單邊就行了舶衬,數(shù)據(jù)幫你劃分了兩個集合了
    }
    for(int i=1;i<n+1;i++){
        memset(used,0,sizeof(used));//嘗試對新的左邊的點進行匹配,現(xiàn)在used數(shù)組要清0
        if(find(i))//如果這個新點可以匹配赎离,匹配數(shù)就++
        ans++;
    }
    cout<<ans;
    return 0;
}

這個遞歸過程我寫的可能還是有點不太明白逛犹,hh,問題不大梁剔,這種算法寫一遍就能理解了虽画,光看肯定是不行的,下篇見

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荣病,一起剝皮案震驚了整個濱河市码撰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌众雷,老刑警劉巖灸拍,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件做祝,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸡岗,警方通過查閱死者的電腦和手機混槐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轩性,“玉大人声登,你說我怎么就攤上這事〈眨” “怎么了悯嗓?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長卸察。 經(jīng)常有香客問我脯厨,道長,這世上最難降的妖魔是什么坑质? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任合武,我火速辦了婚禮,結(jié)果婚禮上涡扼,老公的妹妹穿的比我還像新娘稼跳。我一直安慰自己,他們只是感情好吃沪,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布汤善。 她就那樣靜靜地躺著,像睡著了一般票彪。 火紅的嫁衣襯著肌膚如雪红淡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音,去河邊找鬼露筒。 笑死烘绽,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遂黍。 我是一名探鬼主播终佛,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼雾家!你這毒婦竟也來了铃彰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤芯咧,失蹤者是張志新(化名)和其女友劉穎牙捉,沒想到半個月后竹揍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡邪铲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年芬位,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片带到。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡昧碉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揽惹,到底是詐尸還是另有隱情被饿,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布搪搏,位于F島的核電站狭握,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏疯溺。R本人自食惡果不足惜论颅,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喝检。 院中可真熱鬧嗅辣,春花似錦、人聲如沸挠说。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽损俭。三九已至蛙奖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杆兵,已是汗流浹背雁仲。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留琐脏,地道東北人攒砖。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像日裙,于是被迫代替她去往敵國和親吹艇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容