km算法------poj3686

此题为一个建模很好的题,有点坑~~~~~~

注:

1.不加return 0;会超时

2.输出一定要%.6f\n

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
const int maxn=2501,maxm=51,inf=-10000010;
int w[maxm][maxn],lx[maxm],ly[maxn],d[maxn],slack[maxn];
int nx,ny,n,m,tmp,t;
bool px[maxm],py[maxn];
double ans;
bool dfs(int x){
	int i;
	px[x]=true;
	for(i=1;i<=ny;i++){
		if(py[i]) continue;
		t=lx[x]+ly[i]-w[x][i];
		if(t==0){
			py[i]=true;
			if(!d[i] || dfs(d[i])){
				d[i]=x;
				return true;
			}
		}else 
			if(slack[i]>t)
			slack[i]=t;
	}
	return false;
}
int main(){
	int i,j,k,x;
	int t1;
	scanf("%d",&t1);
	while(t1){
		memset(ly,0,sizeof(ly));
		memset(d,0,sizeof(d));
		scanf("%d%d",&n,&m);
		ans=0;
		t1--;
		nx=n;
		ny=n*m;
		for(i=1;i<=n;i++){
			tmp=0;
			for(j=1;j<=m;j++){
				scanf("%d",&x);
				for(k=1;k<=n;k++)
					  w[i][++tmp]=-x*k;
			}
		}
		for(i=1;i<=nx;i++){
			lx[i]=0;
			for(j=1;j<=ny;j++)
				if(w[i][j]>lx[i])
					lx[i]=w[i][j];
		}
		for(i=1;i<=n;i++){
			for(j=1;j<=ny;j++)
			    slack[j]=inf;
			while(1){
				for(j=1;j<=ny;j++){
					px[j]=false;
					py[j]=false;
				}
				if (dfs(i))
					break;
				t=inf;
				for(j=1;j<=ny;j++)
					if(!py[j] && t>slack[j])
						t=slack[j];
				for(j=1;j<=nx;j++)
					if(px[j])
						lx[j]-=t;
				for(j=1;j<=ny;j++)
					if(py[j]) ly[j]+=t;
				      else slack[j]-=t;
			}
		}
		for(i=1;i<=ny;i++)
			ans+=w[d[i]][i];
		ans*=-1.0;
		ans/=n;
		printf("%.6f\n",ans);
	}
	return 0;
}


你可能感兴趣的:(km算法------poj3686)