B. Building Company

Problem - B - Codeforces

B. Building Company_第1张图片

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

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

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

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
 
using namespace std;
 
typedef pair PII;
typedef long long ll;
typedef long double ld;
typedef pair PLI;

const int N = 100010;

int res[N];//每个项目的限制
map have;//每种员工有多少人 
map, greater>> q;//每种员工下的项目需要人数 
vector 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 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;
} 

你可能感兴趣的:(日常水题,c++,算法)