完美匹配 KM演算法 HDU總結

2021-08-31 19:33:02 字數 2735 閱讀 4583

[size=medium]kidx 的解題報告

[img]

[b][size=medium]首先獻上模板:[/size][/b]

#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;

}

[b][size=medium][color=green]第一題:[/color][url]

直接輸入w[i][j]邊權值建圖套模板就可以了

[color=green]第二題:[/color][url]

將m的座標記錄到左集,h的座標記錄到右集,w[i][j]表示第i個m到第j個h的距離

w[i][j]=△x+△y 然後因為是求最小值,而km是求最大值

所以只要這樣:w[i][j] = -w[i][j]建圖再套模板輸出【-sum】就ok!

[color=green]第三題:[/color][url]

直接建圖,注意有重邊哦!

[color=violet]if (-c > w[a][b])

w[a][b] = -c;[/color]

當木有完美匹配輸出-1

[color=green]第四題:[/color][url]

跟第三題幾乎一樣

[color=green]第五題:[/color][url]

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

[color=green]第六題:[/color][url]

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

[color=green]第七題:[/color][url]

題目要求匹配最大值和至少要改變多少個原有匹配

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

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

[color=red]設結果是res

最大值:res/100

至少改變個數:n - res%100[/color]

[color=green]第八題:[/color][url]

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

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

[color=red]【字母的最大匹配值/n】[/color]

建圖:【例】

[img]

[img]

[color=green]第九題:[/color][url]

直接按題目要求建圖,注意跟自己匹配的值是0,w[i][i]=0

第十題:[url]

直接按題目要求建圖就可以了

[color=green]第十一題:[/color][url]

建圖:多餘的1分別跟所有的0算出最小距離,例如3,多了2個1,要把他們跟所有0匹配,左集是1,右集是這n個數【限制匹配條件(=0)就可以了】

左集個數為m,表示有多少個1需要移動

[color=violet]m = 0;

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

}}[/color]

[color=green]第十二題:[/color][url]

這題比較容易超時……

用stl的map把字串對映為序號

[color=violet]m1.clear();

m2.clear();

k1 = k2 = 1;

while (q--)

[/color]

[color=green]第十三題:[/color][url]

這題要讀懂題目意思!

題意:n艘船要分別回到n個碼頭,另外有m個採礦點,一開始n艘船所在採礦點已經給出,採礦點與採礦點之間給出k條路【雙向的】,碼頭與採礦點之間給出p條路,[color=red]由於船進入碼頭後就不會出來,所以這條路是單向的![/color]

實現:最短路+km

[color=green]第十四題:[/color][url]

題意:n×n的矩陣中,沒行找乙個元素,每個元素之間不可同列,求這n個元素的最大值-最小值的最小差

思路:暴力列舉差值【由於元素的值0<= x <=100, 差值的範圍也只能是[0,100]】

匈牙利檢驗就可以了

[color=violet]bool km (int low, int high)

return true;

}[/color]

[color=green]第十五題:[url]

預設匹配是w[i][i]

si打贏xj,w[i][j] = v[i]

如果si輸了,w[i][j] = -v[i]

所有權值擴大100倍,w[i][i]++優先匹配

相似度=(res%100*100/n)%

[/size][/b]

km演算法與最佳匹配

km演算法 該演算法是通過給每個頂點乙個標號 叫做頂標 來把求最大權匹配的問題轉化為求完備匹配的問題的。設頂點xi的頂標為a i 頂點yj的頂標為b j 頂點xi與yj之間的邊權為w i,j 在演算法執行過程中的任一時刻,對於任一條邊 i,j a i b j w i,j 始終成立。km演算法的正確性...

J Spy(多重匹配KM演算法)

隨機打,最後答案乘n,因為我方等概率的遇見敵人,相當於與n個敵人都打一遍,然後貢獻累加作為匹配邊權 bfs版本的km include include include include using namespace std typedef long long ll const int n 510 ll...

關於km演算法 最佳匹配 的個人總結 模板

km演算法具體講解請看 本文只是模板 include include includeconst int inf 0x3f3f3f3f using namespace std int book 1001 記錄當前男生是否已經被哪個女生選中,單身為0 int used boy 1001 記錄哪些男生在這...