dfs

来源:互联网 发布:em算法应用实例 编辑:程序博客网 时间:2024/06/09 22:21

题目大意:

  R1公司的CEO要给员工发奖金,员工一个个地进CEO的办公室领奖金。但有的员工之间有债务关系,若A君欠B君的钱,当A君领完奖金后下一个领奖金的是B君的时候,他们就会相遇,A君就要马上还钱给B君,那么A君领到奖金的高兴心情也就变得没有那么高兴了。CEO不希望出现这种情况,要你帮他列出一个不会发生这种情况的召唤员工的顺序~若无这种顺序则输出-1.(不会出现A欠B钱,B也欠A钱的情况)

解题思路:

  比赛时做完ABC没时间没看这题看的E题,后来做的时候刚开始以为是求一个欧拉道路,画了草图之后发现不是,研究了下发现是有向图dfs顺序输出。因为有可能不是连通图,所以要把整个森林的节点都输出一次。


[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <cstdio>  
  2. #include <cmath>  
  3. #include <cstring>  
  4. #include <algorithm>  
  5.   
  6. using namespace std;  
  7.   
  8. int n, m;  
  9. vector<int> g[30005];  
  10. int vis[30005];  
  11.   
  12. void dfs (int u)  
  13. {  
  14.     if (vis[u]) // 递归边界1  
  15.         return;  
  16.     vis[u]=1;  
  17.     for (int v=0; v<g[u].size(); v++) // 递归边界2:树中最底层的结点没有指向下一个结点的边  
  18.     {  
  19.         dfs(g[u][v]); // dfs  
  20.     }  
  21.     printf("%d ", u); // 输出当前结点  
  22. }  
  23.   
  24. int main()  
  25. {  
  26.   
  27.     memset(vis, 0, sizeof(vis));  
  28.     scanf("%d %d", &n, &m);  
  29.     while (m--)  
  30.     {  
  31.         int a, b;  
  32.         scanf("%d %d", &a, &b);  
  33.         g[a].push_back(b); // 按题目要求,输出时b在前a在后 所以压边时压成a->b的边 后面调用dfs逆序输出刚好反转成顺序的结点  
  34.     }  
  35.     for (int i=1; i<=n; i++) // 遍历每个结点 若找到森林中未访问过的树的结点 则进行dfs  
  36.     {  
  37.         if (!vis[i])  
  38.             dfs(i);  
  39.     }  
  40.     puts("");  
  41.     return 0;  
  42. }  
0 0
原创粉丝点击