hdu2255 奔小康赚大钱 KM 算法

Posted poorpool

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu2255 奔小康赚大钱 KM 算法相关的知识,希望对你有一定的参考价值。

参见这里

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n, a[305][305], mat[305], exu[305], exv[305], qiw[305];
const int oo=0x3f3f3f3f;
bool viu[305], viv[305];
bool dfs(int x){
	viu[x] = true;
	for(int i=1; i<=n; i++){
		if(viv[i])	continue;
		int gap=exu[x]+exv[i]-a[x][i];
		if(!gap){
			viv[i] = true;
			if(!mat[i] || dfs(mat[i])){
				mat[i] = x;
				return true;
			}
		}
		else qiw[i] = min(qiw[i], gap);
	}
	return false;
}
int main(){
	while(scanf("%d", &n)!=EOF){
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				scanf("%d", &a[i][j]);
		memset(mat, 0, sizeof(mat));
		memset(exu, 0, sizeof(exu));
		memset(exv, 0, sizeof(exv));
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				exu[i] = max(exu[i], a[i][j]);
		for(int i=1; i<=n; i++){
			memset(qiw, 0x3f, sizeof(qiw));
			while(true){
				memset(viu, 0, sizeof(viu));
				memset(viv, 0, sizeof(viv));
				if(dfs(i))	break;
				int tmp=oo;
				for(int j=1; j<=n; j++)
					if(!viv[j])
						tmp = min(tmp, qiw[j]);
				for(int j=1; j<=n; j++){
					if(viu[j])	exu[j] -= tmp;
					if(viv[j])	exv[j] += tmp;
					else	qiw[j] -= tmp;
				}
			}
		}
		int ans=0;
		for(int i=1; i<=n; i++)
			ans += a[mat[i]][i];
		printf("%d\\n", ans);
	}
	return 0;
}

以上是关于hdu2255 奔小康赚大钱 KM 算法的主要内容,如果未能解决你的问题,请参考以下文章

HDU-2255-奔小康赚大钱(KM算法)

hdu2255 奔小康赚大钱 KM 算法

hdu2255 奔小康赚大钱 km算法解决最优匹配(最大权完美匹配)

hdu 2255奔小康赚大钱 KM算法模板

HDU 2255 奔小康赚大钱 KM算法题解

HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法