Gym 101128A :Promotions (Southwestern Europe Regional Contest )
題意
?一個公司里有E個員工P個上下級關系。這個公司有一種晉升制度。如果要晉升員工a,那么必須要先晉升a的所有領導。給出一個區間[A,B],如果要晉升A個員工,有哪些員工是一定會被晉升的?如果要晉升B個員工,有哪些員工是一定會被晉升的?如果晉升B個員工,有哪些員工是一定不會被晉升的?
分析
這個描述再加上那個樣例的圖片實在太TM像拓撲排序了啊!當時在場上寫了個拓撲排序然后WA的很慘
如果要晉升A個員工,哪些員工是一定會被晉升的?當這個員工的下屬數量(包括他自己)大于n-A的時候,則必須晉升它
那么對于每個員工跑dfs統計出它下屬的數量就可以。
如果要晉升B個員工,哪些員工是一定不會被晉升的?當這個員工的上司數量大于B的時候,它一定不會被晉升。那么把圖反過來,再對每個員工跑一遍dfs就可以,方法和上面一樣。
代碼如下:
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 #include <vector> 6 #include <queue> 7 using namespace std; 8 const int maxn=5000+10; 9 const int maxm=20000+10; 10 vector<int>G[3][maxn]; 11 int vis[maxn]; 12 int A,B,E,P; 13 int a,b; 14 int ansa,ansb,ansc; 15 int num[maxn]; 16 void dfs(int n,int u,int o){ 17 vis[u]=1; 18 num[o]++; 19 for(int i=0;i<G[n][u].size();i++){ 20 int v=G[n][u][i]; 21 if(!vis[v]) 22 dfs(n,v,o); 23 } 24 return ; 25 } 26 int main(){ 27 ansa=ansb=ansc=0; 28 scanf("%d%d%d%d",&A,&B,&E,&P); 29 memset(num,0,sizeof(num)); 30 for(int i=1;i<=P;i++){ 31 scanf("%d%d",&a,&b); 32 G[1][a].push_back(b); 33 G[2][b].push_back(a); 34 } 35 for(int i=0;i<E;i++){ 36 memset(vis,0,sizeof(vis)); 37 dfs(1,i,i); 38 } 39 for(int i=0;i<E;i++){ 40 if(num[i]>E-A)ansa++; 41 if(num[i]>E-B)ansb++; 42 } 43 memset(num,0,sizeof(num)); 44 for(int i=0;i<E;i++){ 45 memset(vis,0,sizeof(vis)); 46 dfs(2,i,i); 47 } 48 49 for(int i=0;i<E;i++){ 50 if(num[i]>B)ansc++; 51 } 52 cout<<ansa<<endl; 53 cout<<ansb<<endl; 54 cout<<ansc<<endl; 55 return 0; 56 } View Code另外當時想的拓撲排序為啥是錯的呢,當時是覺得跑一遍拓撲排序然后找出每個拓撲順序上員工的數量,然后由低到高加起來只要現在的數量不超過A。然后這就是一定會被晉升的人數。但是這個晉升關系和拓撲序是有區別的。就拿樣例來說,如果要晉升兩個員工,按照這種拓撲思想,0和6都是一定會被晉升的,因為他們的拓撲序都是第一個,但題目并不是這個意思,因為晉升了0以后,1也可以得到晉升了,那么晉升兩個員工有可能晉升0和6,也可能晉升0和1,所以一定被晉升的只有0結點自己。
轉載于:https://www.cnblogs.com/LQLlulu/p/8818170.html
總結
以上是生活随笔為你收集整理的Gym 101128A :Promotions (Southwestern Europe Regional Contest )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java多态实例
- 下一篇: 软件补丁问题(网络流24题)