0
点赞
收藏
分享

微信扫一扫

奔小康赚大钱 HDU - 2255最大权值匹配 KM模板

郝春妮 2022-06-29 阅读 53

​​传送门​​​ 思路:原来想用dfs做,然后果断wa Tle,后来才知道要用KM最大权值匹配,学习了。
AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<cctype>
#include<stack>
#include<map>
#include<string>
#include<cstdlib>
#define min(a,b) a>b?b:a
#define max(a,b) a>b?a:b
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 400, INF = 0x7fffffff;
int usedx[maxn], usedy[maxn], w[maxn][maxn], bx[maxn], by[maxn], cx[maxn], cy[maxn];
int nx, ny, n, minn, max_value;
int dfs(int u)
{
usedx[u] = 1;
for(int i=1; i<=ny; i++)
{
if(usedy[i] == -1)
{
int t = bx[u] + by[i] - w[u][i];
if(t == 0)
{
usedy[i] = 1;
if(cy[i] == -1 || dfs(cy[i]))
{
cy[i] = u;
cx[u] = i;
return 1;
}
}
else if(t > 0)
minn = min(minn, t);
}
}
return 0;
}
int km()
{
mem(cx, -1);
mem(cy, -1);
mem(bx, -1);
mem(by, 0);
for(int i=1; i<=nx; i++)
for(int j=1; j<=ny; j++)
bx[i] = max(bx[i], w[i][j]);
for(int i=1; i<=nx; i++)
{
while(1)
{
minn = INF;
mem(usedx, -1);
mem(usedy, -1);
if(dfs(i)) break;
for(int j=1; j<=nx; j++)
if(usedx[j] != -1) bx[j] -= minn;
for(int j=1; j<=ny; j++)
if(usedy[j] != -1) by[j] += minn;
}
}
max_value = 0;
for(int i=1; i<=nx; i++)
if(cx[i] != -1)
max_value += w[i][cx[i]];
printf("%d\n",max_value);
return 1;
}

int main()
{
while(~scanf("%d",&n))
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d",&w[i][j]);
nx = ny = n;
km();
}
return 0;
}


举报

相关推荐

0 条评论