hdu2255 奔小康賺大錢,最大權匹配,KM演算法

2022-07-23 21:00:24 字數 1510 閱讀 5998

點選開啟鏈結

最大權匹配

km演算法

演算法步驟:

設頂點xi的頂標為a[i],頂點yi的頂標為b[i]

ⅰ.初始時。a[i]為與xi相關聯的邊的最大權值。b[j]=0。保證a[i]+b[j]>=w(i,j)成立

ⅱ.當相等子圖中不包括完備匹配時,就適當改動頂標以擴大相等子圖,直到找到完備匹配為止

ⅲ.改動頂標的方法

當從xi尋找交錯路失敗後,得到一棵交錯樹,它的全部葉子節點都是x節點。對交錯樹中x頂點的頂標降低d值,y頂點的頂標新增d值,對於圖中全部的邊(i,j),

能夠看到:

i和j都不在交錯樹中,邊(i,j)仍然不屬於相等子圖  

i和j都在交錯樹中,邊(i,j)仍然屬於相等子圖

i不在交錯樹中。j在交錯樹中,a[i]+b[j]擴大。邊(i,j)不屬於相等子圖

i在交錯樹,j不在交錯樹中,邊(i,j)有可能增加到相等子圖中

為了使a[i]+b[j]>=w(i,j)始終成立,且至少有一條邊增加到相等子圖中,d=min,i在交錯樹中,j不在交錯樹中

時間複雜度:須要找o(n)次增廣路。每次增廣最多須要改動o(n)次頂標。每次改動頂標時列舉邊來求d值,複雜度為o(n2),總的複雜度為o(n4).簡單優化能夠減少到o(n3),每乙個y頂點乙個「鬆弛量」函式slack,每次開始找增廣路時初始化為無窮大。

在尋找增廣路的過程中,檢查邊(i,j)時。假設不在相等子圖中,則讓slack[j]變成原值與a[i]+b[j]-w[i,j]的較小值。這樣。在改動頂標時,取全部不在交錯樹中的y頂點的slack值中的最小值作為d值就可以。但還要注意一點:改動頂標後,要把全部的slack值都減去d。

#include #include #include #include #include #include #include #include #include #include #include #define for0(a,b) for(a=0;a=b;--i)

using namespace std;

typedef long long ll;

const int maxn = 310;

const int inf = 1e9;

/*km演算法

*o(nx*nx*ny)

*求最大權匹配

*若求最小權匹配,可將權值取相反數,結果再取相反數。

*/int nx, ny;

int g[maxn][maxn];

int linker[maxn], lx[maxn], ly[maxn];//y中各點匹配狀態,x,y中的頂標

int slack[maxn];

bool visx[maxn], visy[maxn];

bool dfs(int x)

return false;

}int km()

for(int x=0; xslack[i])

d = slack[i];

for(int i=0; i

hdu2255奔小康賺大錢

problem description 傳說在遙遠的地方有乙個非常富裕的村落,有一天,村長決定進行制度改革 重新分配房子。這可是一件大事,關係到人民的住房問題啊。村里共有n間房間,剛好有n家老百姓,考慮到每家都要有房住 如果有老百姓沒房子住的話,容易引起不安定因素 每家必須分配到一間房子且只能得到一...

HDU 2255奔小康賺大錢

hdu 2255奔小康賺大錢 題意 村里共有n間房間,剛好有n家老百姓,考慮到每家都要有房住 每家必須分配到一間房子且只能得到一間房子 由於老百姓都比較富裕,他們都能對每一間房子在他們的經濟範圍內出一定的 比如有3間房子,一家老百姓可以對第一間出10萬,對第2間出2萬,對第3間出20萬.每組資料的第...

HDU 2255 奔小康賺大錢

include include includeusing namespace std define inf 0x3f3f3f3f define n 300 10 int w n n n int lx n ly n 頂標 int match n int s n t n slack n s i 和t i...