匈牙利算法

備個份,後面用到再加題目

M67大神的幾句話講解:http://www.matrix67.com/blog/archives/39

二分圖最大匹配問題匈牙利算法

    研究了幾個小時,終於明白了。說穿了,就是你從二分圖中找出一條路徑來,讓路徑的起點和終點都是還沒有匹配過的點,並且路徑經過的連線是一條沒被匹配、一條已經匹配過,再下一條又沒匹配這樣交替地出現。找到這樣的路徑後,顯然路徑裏沒被匹配的連線比已經匹配了的連線多一條,於是修改匹配圖,把路徑裏所有匹配過的連線去掉匹配關係,把沒有匹配的連線變成匹配的,這樣匹配數就比原來多1個。不斷執行上述操作,直到找不到這樣的路徑爲止。

僞代碼:

bool 尋找從k出發的對應項出的可增廣路
{
	while (從鄰接表中列舉k能關聯到頂點j)
	{
		if (j不在增廣路上)
		{
			把j加入增廣路;
			if (j是未蓋點 或者 從j的對應項出發有可增廣路)
			{
				修改j的對應項爲k;
				則從k的對應項出有可增廣路,返回true;
			}
		}
	}
	則從k的對應項出沒有可增廣路,返回false;
}
 
void 匈牙利hungary()
{
	for i->1 to n
	{
		if (則從i的對應項出有可增廣路)
			匹配數++;
	}
	輸出 匹配數;
}
模板代碼:
bool find (int x)
{
  for (int i=0;i<G[x].size ();i++){
	Edge& e=theEdge[G[x][i]];
	if (!vis[e.to]){
	  vis[e.to]=1;
	  if (match[e.to]==0 || find (match[e.to])){
		match[e.to]=x;
		return true;
	  }
	}
  }
  return false;
}
int hungary ()
{
  int cnt=0;
  memset (match,0,sizeof (match));
  for (int i=0;i<n;i++){
	memset (vis,0,sizeof (vis));
	if (find (g2l[i]))
	  cnt++;
  }
  return cnt;
}



發佈了90 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章