B. Building Company

Problem - B - Codeforces

 可以用若干个优先队列每一种员工可能会参与到的所有项目,从小到大排序

给每一个项目加上若干个限制,每有一种员工达到要求,限制就减一,限制为0时就收获这个项目的奖励

可以将每次奖励存到队列中去,每次奖励使某种员工增加时,就看这种员工可能参加的剩余的项目中有没有能减少限制的

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
 
using namespace std;
 
typedef pair<int, int> PII;
typedef long long ll;
typedef long double ld;
typedef pair<ll, int> PLI;

const int N = 100010;

int res[N];//每个项目的限制
map<int, ll> have;//每种员工有多少人 
map<int, priority_queue<PLI, vector<PLI>, greater<PLI>>> q;//每种员工下的项目需要人数 
vector<PII> reward[N];
int ans;

int main()
{
	IOS
	int n;
	cin >> n;
	for(int i = 0; i < n; i ++)
	{
		int a, b;
		cin >> a >> b;
		have[a] = b;
	}
	
	queue<PII> q_rew;
	
	cin >> n;
	for(int i = 1; i <= n; i ++)
	{
		int m;
		cin >> m;
		for(int j = 0; j < m; j ++)
		{
			int a, b;
			cin >> a >> b;
			if(b > have[a])
			{
				res[i] ++;
				q[a].push({b, i});
			}
		}
		cin >> m;
		for(int j = 0; j < m; j ++)
		{
			int a, b;
			cin >> a >> b;
			reward[i].push_back({a, b});//a类员工,b个人 
		}
		
		if(!res[i])
		{
			ans ++;
			for(int j = 0; j < m; j ++)
			{
				q_rew.push({reward[i][j].first, reward[i][j].second});
			}
		}
	}
	
	while(q_rew.size())
	{
		int A = q_rew.front().first, B = q_rew.front().second;
		q_rew.pop();
		
		have[A] += B;
		while(q[A].size())
		{
			int t = q[A].top().first;
			if(t > have[A])break;
			int num = q[A].top().second;
			q[A].pop();
			
			res[num] --;
			if(!res[num])
			{
				ans ++;
				for(int i = 0; i < reward[num].size(); i ++)
				{
					int a = reward[num][i].first, b = reward[num][i].second;
					q_rew.push({a, b});
				}
			}
		}
	}
	
	cout << ans;
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值