HDU 2255 奔小康赚大钱

奔小康赚大钱

题解

抄了一下午代码,抄错了一个字母。

//Twenty
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 0xfffffff
const int maxn=305;
typedef long long LL;
using namespace std;
int n,cx[maxn],cy[maxn],x[maxn],y[maxn],pr[maxn],slack[maxn];
int a[maxn][maxn];

int find(int u) {
	x[u]=1;
	for(int i=1;i<=n;i++) {
		if(!y[i]){
			if(cx[u]+cy[i]==a[u][i]) {
				y[i]=1;
				if(pr[i]==-1||find(pr[i])) {
					pr[i]=u;
					return 1;
				}
			}
			else slack[i]=min(slack[i],-a[u][i]+cx[u]+cy[i]);
        }
	}
	return 0;
}

void work() {
	memset(pr,-1,sizeof(pr));
	memset(cy,0,sizeof(cy));
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=n;j++) slack[j]=INF;
		for(;;) {
			memset(x,0,sizeof(x));
			memset(y,0,sizeof(y));
			if(find(i)) break;
			int d=INF;
			for(int j=1;j<=n;j++) 
				if(!y[j]&&d>slack[j]) 
					d=slack[j];	
			if(d==INF) return;
			for(int j=1;j<=n;j++) {
				if(x[j]) cx[j]-=d;
				if(y[j]) cy[j]+=d;
				else slack[j]-=d;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=n;i++) 
		ans+=a[pr[i]][i];
	printf("%d\n",ans);
}

void init() {
    while(~scanf("%d",&n)) {
	    for(int i=1;i<=n;i++) {
		    cx[i]=-INF;
		    for(int j=1;j<=n;j++) {
				scanf("%d",&a[i][j]);
				cx[i]=max(cx[i],a[i][j]);
			}
		}
		work();
	}
}

int main()  {
    init();
    return 0;
}

  

转载于:https://www.cnblogs.com/Achenchen/p/7744485.html

你可能感兴趣的:(HDU 2255 奔小康赚大钱)