Promotions Gym - 101128A dfs+思维

Promotions
The Fair Inc. administration decided to promote the best
employees and limited the number of promotions to a fixed
interval [A, B]. The directors compared the employees’
performance and their evaluations resulted in a consistent
precedence relation among employees, which has to be respected
by promotions. This means that, for every pair of
employees x and y, if x outperformed y, then y may be
promoted only if x is promoted.
In order to understand whether the data collected so far is
enough for ensuring fairness, the executive chairman wants to
know:
• How many employees will certainly be promoted in the
interval endpoints (i.e., if the number of promotions is
A and if the number of promotions is B).
• How many employees have no possibility of being
promoted (even if the number of promotions is B).
Consider the example depicted in the figure. There are seven
employees and eight precedence rules. An arrow from an
employee x to an employee y means that x outperformed y. The number of promotions is
limited to the interval [3, 4]. Therefore:
• If there are only three promotions, the promoted employees must be:
– either Anne, Bob and Greg,
– or Anne, Eve and Greg.
In this case, two employees (Anne and Greg) will certainly be promoted. Notice that,
with the current information, Bob and Eve may or may not win a promotion.
• If there are four promotions, the promoted employees have to be:
– Anne, Bob, Eve and Greg.
So, with four promotions, four employees (Anne, Bob, Eve and Greg) will certainly
be promoted and three employees (Cora, Dan and Fred) have no possibility of being

promoted.

Task
Write a program that, given the interval of the number of promotions, the set of employees
and the precedence relation among them, computes, for each of the interval endpoints, the
number of employees that will certainly be promoted, and the number of employees that
have no possibility of being promoted.
The precedence relation is consistent in the sense that, if an employee x outperformed an
employee y, y did not outperform (directly or indirectly) x.
Input
The first line of the input has four space separated integers: A, B, E, and P. A and B are
the interval endpoints, E is the number of employees and P is the number of precedence
rules. Employees are identified by integers, ranging from 0 to E − 1.
Each of the following P lines contains two distinct space separated integers, x and y, which
indicate that employee x outperformed employee y.
Constraints
1 ≤ A < B < E Interval endpoints.
2 ≤ E ≤ 5 000 Number of employees.
1 ≤ P ≤ 20 000 Number of precedence rules.
Output
The output consists of three lines. The first line contains the number of employees that
will certainly be promoted if there are A promotions. The second line contains the number
of employees that will certainly be promoted if there are B promotions. The third line
contains the number of employees that have no possibility of being promoted (even if there
are B promotions).
Sample Input
3 4 7 8
0 4
1 2
1 5
5 2
6 4
0 1
2 3
4 5

Sample Output
2
4
3

题意:给定N个人,每个人有一个performance-value,现在要选择一些人提拔,只有比x的performance-value高的人都选完了x才能被选,给出m对人的performance-value相对大小,问:

如果选L个人有多少个人是一定会被选上的。

如果选R个人有多少个人是一定会被选上的。

即使选R个人有多少个人一定不会被选上。

思路:一开始还以为是拓扑排序,但是写完了怎么交都是wa1,赛后看题解发现就是简单的dfs。。至今也不明白拓扑排序为什么不对,感觉也能用来解这个题的。

正解:我们先建一个正向图搜出每个点有多少后继,然后在反向图上搜每个点有多少前驱,选X个人,若结点后继个数大于N-X则该节点一定会被选上,反之,若结点前驱个数大于等于X则一定选不上。

代码:

#include<bits/stdc++.h>
using namespace std;
vector<int>mp[5005],mp1[5005];
bool vis[5005];
int dfs(int k)
{
	if(vis[k])return 0;
	vis[k]=1;
	int ans=1;
	for(int i=0;i<mp[k].size();i++)
	ans+=dfs(mp[k][i]);
	return ans;
}
int dfs1(int k)
{
	if(vis[k])return 0;
	vis[k]=1;
	int ans=1;
	for(int i=0;i<mp1[k].size();i++)
	ans+=dfs1(mp1[k][i]);
	return ans;
}
int main()
{
		int l,r,n,m,u,v;
		scanf("%d%d%d%d",&l,&r,&n,&m);
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&u,&v);
			mp[u].push_back(v);
			mp1[v].push_back(u);
		}
		int ans1=0,ans2=0;
		for(int i=0;i<n;i++)
		{
			memset(vis,0,sizeof(vis));
			int temp=dfs(i);
			if(n-temp<l)
			ans1++;
			if(n-temp<r)
			ans2++;
		}
		cout<<ans1<<endl<<ans2<<endl;
		ans1=0;
		for(int i=0;i<n;i++)
		{
			memset(vis,0,sizeof(vis));
			if(dfs1(i)>r)
			ans1++;
		}
		cout<<ans1<<endl;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值