BZOJ 2557: [Poi2011]Programming Contest 匈牙利算法

2557: [Poi2011]Programming Contest

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 188  Solved: 65
[Submit][Status][Discuss]

Description

Bartie and his friends compete in the Team Programming Contest. There are n contestants on each team, and each team has access to n  computers. The contest lasts t minutes, during which the contestants are to solve m programming problems. Furthermore, penalties are imposed on the teams: solving a problem s minutes since the beginning of the contest amounts to  s penal points. The team that solved the most problems wins the contest, with ties broken in favour of the team with smaller penalty.
On the contest day Bartie quickly glances over the problem statements and distributes them among his teammates. He knows his team so well that he can exactly assess who is able to solve which problem. Solving any problem takes any contestant that is able to solve it exactly r minutes of using the computer.
Bartie's team did not fare well in this year's contest. Bartie is obsessed with the thought that it might be his fault, due to wrong decisions regarding the distribution of problems. He asks you to write a program that, given what Bartie knew at the beginning of the contest, determines the best possible result of Bytie's team, together with the assignment of problems to team members that attains the result.

n个人m个题目,每个题要r分钟完成。比赛有t分钟。给出每个人会做哪些题目,请你安排一个每个人在什么时候做什么题目,使得做出来的题目数最多。在做题数一样多的情况下,罚时尽量小。
 

Input

Five integers n,m,r,t and k(1<=n,m<=500,1<=r,t<=10^6)) are given in the first line of the standard input, separated by single spaces. These denote, respectively: the number of contestants on a team, the number of problems, the time it takes a contestant to solve a problem, the duration of the contest, and the number of contestant-problem pairs given on the input. Each of the following k lines holds two integers a and b(1<=a<=n,1<=b<=m)), separated by a single space, denoting that the contestant a is able to solve the problem b. Each such pair appears at most once in the input.
In tests worth at least 30% of the points it additionally holds that n,m<=100.

Output

In the first line of the standard output the best possible result of Bytie's team should be printed as two numbers separated by a single space: the number of solved problems z and the total penal points.

Sample Input

2 4 3 15 4
1 1
2 3
1 4
1 3

Sample Output

3 12

费用流就是原点向每个人连 1r 2r 2r 费用的边

看别人的blog说不太好跑 liu_runda 动态加边过了

但我估计多路增广一点也不虚

然而 我还是屈服于commonc了

http://blog.csdn.net/commonc/article/details/52297167


#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;

typedef long long ll;
typedef double db;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f*x;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}

const int N=1010,M=1000100;

int last[N],ecnt;
struct EDGE{int to,nt;}e[M];
inline void add(int u,int v)
{e[++ecnt]=(EDGE){v,last[u]};last[u]=ecnt;}

int vis[N],match[N],tim;

bool hungray(int u)
{
	for(int i=last[u],v;i;i=e[i].nt)
	{
		v=e[i].to;
		if(vis[v]==tim)continue;
		vis[v]=tim;
		if(!match[v]||hungray(match[v]))
		{
			match[v]=u;
			return 1;
		}
	}
	return 0;
}

bool skip[N];

int main()
{
	int n=read(),m=read(),R=read(),T=read(),K=read();
	register int i,j,u,v,ans1(0),ans2(0);
	for(i=1;i<=K;++i)
	{
		u=read();v=read();
		add(u,v+n);
	}
	for(i=1;i*R<=T;++i)
	{
		for(j=1;j<=n;++j)
			if(!skip[j])
			{
				tim++;
				hungray(j)?(ans1++,ans2+=i):skip[j]=1;
			}
		if(ans1==m)break;
	}
	cout<<ans1<<" "<<1ll*ans2*R<<endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值