HDU 2255-奔小康賺大錢(Kuhn-Munkras演算法/KM演算法-完備匹配下的最大權匹配)
奔小康賺大錢
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7423 Accepted Submission(s): 3301
Problem Description
傳說在遙遠的地方有一個非常富裕的村落,有一天,村長決定進行制度改革:重新分配房子。
這可是一件大事,關係到人民的住房問題啊。村裡共有n間房間,剛好有n家老百姓,考慮到每家都要有房住(如果有老百姓沒房子住的話,容易引起不安定因素),每家必須分配到一間房子且只能得到一間房子。
另一方面,村長和另外的村領導希望得到最大的效益,這樣村裡的機構才會有錢.由於老百姓都比較富裕,他們都能對每一間房子在他們的經濟範圍內出一定的價格,比如有3間房子,一家老百姓可以對第一間出10萬,對第2間出2萬,對第3間出20萬.(當然是在他們的經濟範圍內).現在這個問題就是村領導怎樣分配房子才能使收入最大.(村民即使有錢購買一間房子但不一定能買到,要看村領導分配的).
這可是一件大事,關係到人民的住房問題啊。村裡共有n間房間,剛好有n家老百姓,考慮到每家都要有房住(如果有老百姓沒房子住的話,容易引起不安定因素),每家必須分配到一間房子且只能得到一間房子。
另一方面,村長和另外的村領導希望得到最大的效益,這樣村裡的機構才會有錢.由於老百姓都比較富裕,他們都能對每一間房子在他們的經濟範圍內出一定的價格,比如有3間房子,一家老百姓可以對第一間出10萬,對第2間出2萬,對第3間出20萬.(當然是在他們的經濟範圍內).現在這個問題就是村領導怎樣分配房子才能使收入最大.(村民即使有錢購買一間房子但不一定能買到,要看村領導分配的).
Input
輸入資料包含多組測試用例,每組資料的第一行輸入n,表示房子的數量(也是老百姓家的數量),接下來有n行,每行n個數表示第i個村名對第j間房出的價格(n<=300)。
Output
請對每組資料輸出最大的收入值,每組的輸出佔一行。
Sample Input
2
100 10
15 23
Sample Output
123
Source
Recommend
模板題~
有個坑阿!!(╯‵□′)╯︵┻━┻
下面這個不能寫成#define 要不然超時超的想哭啊啊啊O(≧口≦)O!阿摔(╯' - ')╯︵ ┻━┻
const int maxn = 310;
const int INF = 0x3f3f3f3f;
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<malloc.h>
using namespace std;
typedef long long ll;
const int maxn = 310;
const int INF = 0x3f3f3f3f;
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)
{
visx[x] = true;
for(int y = 1; y <= ny; y++)
{
if(visy[y])continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp == 0)
{
visy[y] = true;
if(linker[y] == -1 || DFS(linker[y]))
{
linker[y] = x;
return true;
}
}
else if(slack[y] > tmp)
slack[y] = tmp;
}
return false;
}
int KM()
{
memset(linker,-1,sizeof(linker));
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(int i = 1; i <= nx; i++)
{
lx[i] = -INF;
for(int j = 1; j <= ny; j++)
if(g[i][j] > lx[i])
lx[i] = g[i][j];
}
for(int x = 1; x <= nx; x++)
{
for(int i = 1; i <= ny; i++)
slack[i] = INF;
while(true)
{
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
if(DFS(x))break;
int d = INF;
for(int i = 1; i <= ny; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int i = 1; i <= nx; i++)
if(visx[i])
lx[i] -= d;
for(int i = 1; i <= ny; i++)
{
if(visy[i])ly[i] += d;
else slack[i] -= d;
}
}
}
int res = 0;
for(int i = 1; i <= nx; i++)
if(linker[i] != -1)
res += g[linker[i]][i];
return res;
}
int main()
{
int n;
while(scanf("%d",&n) == 1)
{
for(int i = 1; i <= n; i++)
for(int j =1; j <= n; j++)
scanf("%d",&g[i][j]);
nx = ny = n;
printf("%d\n",KM());
}
return 0;
}
/**
2
100 10
15 23
**/
相關文章
- POJ 3565 Ants (最小權完美匹配 KM演算法)演算法
- hdu2255 二分圖的最佳匹配 KM演算法演算法
- KM演算法——二分圖的最佳匹配演算法
- HDU 2063 匈牙利演算法二分圖的最大匹配演算法
- 二分圖的最大匹配、完美匹配和匈牙利演算法演算法
- poj2400 KM演算法二分圖的完美匹配演算法
- hdu5090 匈牙利演算法二分圖最大匹配問題演算法
- 匈牙利演算法--二分圖的最大匹配演算法
- NLP之逆向最大匹配演算法(BMM)演算法
- 二分圖最大匹配(匈牙利演算法)演算法
- 二分圖的最大匹配的匈牙利演算法演算法
- 求二部圖最大匹配的匈牙利演算法演算法
- 二分圖的最大匹配(匈牙利演算法)程式碼演算法
- 字串匹配基礎下——KMP 演算法字串匹配KMP演算法
- 二分圖最大匹配問題匈牙利演算法演算法
- Uva11383 二分圖的完美匹配(深入理解KM演算法)演算法
- 二分圖最大權完美匹配
- 模式匹配-KMP演算法模式KMP演算法
- 《啊哈!演算法》我要做月老 ——二分圖最大匹配演算法
- 對匈牙利演算法理解——對二分圖進行最大匹配的演算法演算法
- 演算法學習之路|二分圖的最大匹配—匈牙利演算法(Dfs實現)演算法
- 字串匹配演算法(一)字串匹配演算法
- KMP模式匹配演算法KMP模式演算法
- 字串匹配演算法:KMP字串匹配演算法KMP
- KMP字串匹配演算法KMP字串匹配演算法
- 字串匹配KMP演算法初探字串匹配KMP演算法
- 字串匹配-BF演算法和KMP演算法字串匹配演算法KMP
- 字串匹配演算法(三)-KMP演算法字串匹配演算法KMP
- 樸素的模式匹配演算法模式演算法
- 字串匹配的Boyer-Moore演算法字串匹配演算法
- 模式匹配kmp演算法(c++)模式KMP演算法C++
- 字串匹配之KMP《演算法很美》字串匹配KMP演算法
- 字串匹配問題——KMP演算法字串匹配KMP演算法
- 字串匹配之Sunday演算法字串匹配演算法
- 串(2)--模式匹配演算法模式演算法
- c#-SimHash匹配相似-演算法C#演算法
- KM演算法演算法
- 字串匹配演算法(二)-BM演算法詳解字串匹配演算法