hdu 5045 Contest

方法:

      求最大期望只需使得每一个题目匹配的人对应的概率的和最大即可。。。 所以进行多次二分图最大权匹配即可

PS:     

     初始化一定要注意处理好。。。

代码:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define eps 1e-9
#define maxn 12

double m_1[maxn][1111], m_2[maxn][maxn], lx[maxn], ly[maxn], d;
bool visx[maxn], visy[maxn];
int match[maxn], n, m;

void init()
{
	memset(m_1, 0, sizeof(m_1));
	scanf("%d %d",&n,&m);
	for(int i= 1; i<= n; i++)
		for(int j= 1; j<= m; j++)
			scanf("%lf",&m_1[i][j]);		
}

bool dfs(int u)
{
	visx[u]= true;
	for(int i= 1; i<= n; i++)
		if(!visy[i])
		{
			double t= lx[u] + ly[i]- m_2[u][i];
			if(t<= eps && t>= -eps)
			{
				visy[i]= true;
				if(match[i]== -1 || dfs(match[i]))
				{
					match[i]= u;
					return true;
				}
			}
			else if(t> 0)
				d= min(d, t);
		}
	return false;	
}

int main()
{
	int T;
	scanf("%d",&T);
	for(int C= 1; C<= T; C++)
	{
		init();
		double ans= 0;
		for(int x= 1; x<= m; x+= n)
		{
			memset(match, -1, sizeof(match));
			for(int i= 1; i<= n; i++)
			{
				lx[i]= ly[i]= 0;
				for(int j= 1; j<= n; j++)
				{
					m_2[i][j]= m_1[i][x+j-1];
					lx[i]= max(m_2[i][j], lx[i]);
				}
			}
			d= 1<< 30;
			for(int i= 1; i<= n; i++)
			{
				memset(visx, false, sizeof(visx));
				memset(visy, false, sizeof(visy));
				while(!dfs(i))
				{
					for(int j= 1; j<= n; j++)
					{
						if(visx[j]) lx[j]-= d;
						if(visy[j]) ly[j]+= d;
					}
					memset(visx, false, sizeof(visx));
					memset(visy, false, sizeof(visy));
				}
			}
			for(int i= 1; i<= n; i++) 
				ans+= lx[i]+ ly[i];		
		}
		printf("Case #%d: %.5lf\n",C,ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值