奔小康赚大钱 HDU

#pragma GCC optimize (3,"inline","Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x) {
	Finish_read=0;
	x=0;
	int f=1;
	char ch=getchar();
	while(!isdigit(ch)) {
		if(ch=='-')f=-1;
		if(ch==EOF)return;
		ch=getchar();
	}
	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
	x*=f;
	Finish_read=1;
}
const int N=505;
const int inf=2e9+7;
int n;
int wx[N],wy[N],weight[N][N],slack[N];
int belong[N],visx[N],visy[N];
int FindPath(int u) {
	visx[u]=1;
	for(int v=1; v<=n; v++) {
		if(visy[v]) 
			continue;
		int t=wx[u]+wy[v]-weight[u][v];
		if(!t) {
			visy[v]=1;
			if(belong[v]==-1||FindPath(belong[v])) {
				belong[v]=u;
				return 1;
			}
		} else if(slack[v]>t) 
			slack[v]=t;
	}
	return 0;
}

int Km() {
	for(int i=1; i<=n; i++) 
		wx[i]=-inf;
	for(int i=1; i<=n; i++) 
		for(int j=1; j<=n; j++) 
			wx[i]=max(wx[i],weight[i][j]);
	for(int i=1; i<=n; i++) { 
		for(int j=1; j<=n; j++) 
			slack[j]=inf;
		while(1) {
			memset(visx,0,sizeof visx);
			memset(visy,0,sizeof visy);
			if(FindPath(i)) 
				break;
			int ret=inf;
			for(int j=1; j<=n; j++) 
				if(!visy[j]&&ret>slack[j]) 
					ret=slack[j];
			for(int j=1; j<=n; j++) 
				if(visx[j]) 
					wx[j]-=ret;
			for(int j=1; j<=n; j++) 
				if(visy[j]) 
					wy[j]+=ret;
				else 
					slack[j]-=ret;
			}		
	}
	
	int ans=0;
	for(int i=1; i<=n; i++) 
		if(~belong[i]) 
			ans+=weight[belong[i]][i];
	return ans;
}

int main() {
	while(scanf("%d",&n)!=EOF) {
		memset(belong,-1,sizeof belong);
		for(int i=1; i<=n; i++) 
			for(int j=1; j<=n; j++) 
				read(weight[i][j]);
		printf("%d
",Km());
	}
	return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12433188.html