KM演算法入門

2021-09-20 00:09:43 字數 2840 閱讀 2846

km演算法的基本概念:

看這個演算法之前,最好先看下匈牙利演算法,km演算法 是建立在匈牙利演算法基礎上實現的

對於這個演算法最有誤區的地方,個人感覺還是在  x 集合 -d  和 y 集合 + d之後 還要進行

操作,再加上 深搜遞迴操作  ,理解容易產生誤區,在這裡我給出一組模板的測試資料來幫助初學者理解

注意觀察: visx,visy,lx,ly,linky,在呼叫中的變化:

3 40 0 2

0 1 6

1  1 7

2 1  14

2  2  3

模板:(o  ^ 4) 

#define m 505

#define inf 0x3fffffff

bool sx[m], sy[m];

int match[m], w[m][m], n, m, d, lx[m], ly[m];

//n:左集元素個數; m:右集元素個數

void init ()

bool dfs (int u)}}

return false;

}int km ()

memset (match, -1, sizeof(match));

for (i = 0; i < n; i++)

}for (i = 0; i < m; i++)

if (match[i] > -1)

sum += w[match[i]][i];

return sum;

}

改進後的模板(o^3)

/*其實在求最大 最小的時候只要用乙個模板就行了,把邊的權值去相反數即可得到另外乙個.求結果的時候再去相反數即可*/

/*最大最小有一些地方不同。。*/

#include

#include

#include

#include

//赤裸裸的模板啊。。

const int maxn = 101;

const int inf = (1<<31)-1;

int w[maxn][maxn];

int lx[maxn],ly[maxn]; //頂標

int linky[maxn];

int visx[maxn],visy[maxn];

int slack[maxn];

int nx,ny;

bool find(int x)

}else if(slack[y] > t)

slack[y] = t;

}return false; //沒有找到增廣軌(說明頂點x沒有對應的匹配,與完備匹配(相等子圖的完備匹配)不符)

}int km() //返回最優匹配的值

for(i = 0; i < nx; i++)

for(i = 0; i < ny; i++)}}

int result = 0;

for(i = 0; i < ny; i++)

if(linky[i]>-1)

result += w[linky[i]][i];

return result;

}int main()

printf("%d\n",km());

break;

}return 0;

}

題目推薦:

第一題:hdu  2255   奔小康賺大錢

模板不解釋

第二題:hdu 1533  going home

用 w[i][j] = -w[i][j]建圖再套模板 求最大值   輸出【-sum】

第三題:  hdu  1853  cyclic tour

注意是有向圖,和重邊的判斷

第四題:hdu  3488  tour

跟第三題幾乎一樣

第五題:hdu  3435  a new graph game

跟第三題**基本上一樣,只是要雙向建圖,也有重邊

福大 aekdycoin 出的題,好險的題啊,時間跑了 2000+ ;

第六題: hdu 2426  interesting housing problem

注意 題目輸入 |vi| <= 10000

左集是學生,右集是房子,w[i][j] < 0 不可匹配,最後無法完美匹配輸出-1

第七題:hdu 2853  assignment

思路:讓原有匹配更有優勢就可以了 

實現:所有權值擴大100倍,原有匹配【例如a匹配b】w[a][b]+ + 

設結果是res 

最大值:res/100 

至少改變個數:n - res%100

這種處理比較有意思

第八題:hdu 3718

題目求的是兩字串的最大相似度 

思路:因為第乙個串的一種字母只能匹配第二個串的一種字母,所以可以轉化為求 

【字母的最大匹配值/n】 注意輸入 scanf--%s   不要用 %c%*c

匈牙利演算法 KM演算法

匈牙利演算法 求最大匹配,那麼我們希望每乙個在左邊的點都盡量找到右邊的乙個點和它匹配。我們依次列舉左邊的點x的所有出邊指向的點y,若y之前沒有被匹配,那麼 x,y 就是一對合法的匹配,我們將匹配數加一,否則我們試圖給原來匹配y的x 重新找乙個匹配,如果x 匹配成功,那麼 x,y 就可以新增為一對合法...

匈牙利演算法,KM演算法

bool find int x return false 主程式 for i 1 i n i include include include include include include include include include include include include include...

KM演算法板子

原題hdu2255 其實在求最大 最小的時候只要用乙個模板就行了,把邊的權值去相反數即可得到另外乙個.求結果的時候再去相反數即可 最大最小有一些地方不同。include include include include 赤裸裸的模板啊。const int maxn 301 const int inf ...