LA 7272 Promotions(dfs)

https://vjudge.net/problem/UVALive-7272

题意:

公司要提拔人,现在有n个人,现在有m条有向边,A->B表示A的表现比B好,也就是如果B晋升了,那么A肯定会晋升。

现在给出【L,R】,计算出晋升L个人时肯定会晋升的人数,晋升R个人时肯定会晋升的人数,还有肯定不可能晋升的人数。

 

思路:

先说一下计算不可能人数的算法。

这个需要反向建图,我们dfs遍历,假设现在从第i个人开始遍历,遍历得到它的子节点的个数,这就是说如果i晋升的话,他前面的人也都必须要晋升。

如果这个人数大于了限定的晋升人数,那么这个人肯定是不可能晋升的。

剩余两个也是这样分析的,具体参见代码。

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstdio>
 7 using namespace std;
 8 
 9 const int maxn=5000+5;
10 
11 int n, m;
12 int A,B;
13 int num;
14 
15 vector<int> g[maxn];
16 vector<int> r_g[maxn];
17 
18 int vis[maxn];
19 
20 void r_dfs (int u)
21 {
22     if(vis[u])  return;
23     vis[u]=1;
24     num++;
25     for(int i=0;i<r_g[u].size();i++)
26     {
27         r_dfs(r_g[u][i]);
28     }
29 }
30 
31 
32 void dfs (int u)
33 {
34     if(vis[u])  return;
35     vis[u]=1;
36     num++;
37     for(int i=0;i<g[u].size();i++)
38     {
39         dfs(g[u][i]);
40     }
41 }
42 
43 int main()
44 {
45     //freopen("D:\\input.txt", "r", stdin);
46     while (~scanf("%d%d%d%d",&A, &B, &n, &m))
47     {
48         for(int i=0;i<n;i++)  {g[i].clear();r_g[i].clear();}
49         for(int i=0;i<m;i++)
50         {
51             int u,v;
52             scanf("%d%d",&u,&v);
53             g[u].push_back(v);
54             r_g[v].push_back(u);
55         }
56         int ans1=0,ans2=0,ans3=0;
57         for(int i=0;i<n;i++)
58         {
59             memset(vis,0,sizeof(vis));
60             num=-1;
61             r_dfs(i);
62             if(num>=B)  ans3++;
63             memset(vis,0,sizeof(vis));
64             num=-1;
65             dfs(i);
66             if(num>=n-A)  ans1++;
67             if(num>=n-B)  ans2++;
68         }
69         printf("%d\n%d\n%d\n",ans1,ans2,ans3);
70     }
71     return 0;
72 }

 

posted @ 2017-05-19 14:09  Kayden_Cheung  阅读(164)  评论(0编辑  收藏  举报
//目录