• 拓扑排序(一部分)


    DAG有向无环图又被称为拓扑图,拓扑序列指的是将每个节点能按照起点到终点的顺序排列。

    例一:活动 - AcWing

    板子题,入度 | 出度

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 1e5 + 10;
    6. int n, m;
    7. int e[N], ne[N], h[N], idx;
    8. int d[N]; // 表示入度
    9. queue<int> q, ans;
    10. void add(int a, int b)
    11. {
    12. e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    13. }
    14. bool topsort() // 其实就是bfs
    15. {
    16. for(int i = 1; i <= n; i ++ )
    17. {
    18. if(!d[i])
    19. {
    20. q.push(i);
    21. }
    22. }
    23. while(q.size())
    24. {
    25. int t = q.front();
    26. ans.push(t);
    27. q.pop();
    28. for(int i = h[t]; i != -1; i = ne[i]) // 遍历入度为0后的每一个点,寻找下一个入度=0
    29. {
    30. int j = e[i];
    31. d[j] --;
    32. if(!d[j]) q.push(j);
    33. }
    34. }
    35. return ans.size() == n;
    36. }
    37. int main()
    38. {
    39. cin >> n >> m;
    40. memset(h, -1, sizeof h);
    41. while(m -- )
    42. {
    43. int a, b;
    44. cin >> a >> b;
    45. add(a, b);
    46. d[b] ++;
    47. }
    48. if(topsort()) // 存在拓扑序列
    49. {
    50. while(ans.size())
    51. {
    52. cout << ans.front() << ' ';
    53. ans.pop();
    54. }
    55. }
    56. else
    57. {
    58. puts("-1");
    59. }
    60. return 0;
    61. }

    例二:P1113 杂务 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    这题得到了一个拓扑序之后,能够算出同时进行的多个杂物所需时间,用a去记忆答案

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 1e4 + 10;
    6. int n;
    7. vector<int> e[N]; // 邻接表
    8. int ans, a[N], len[N];
    9. int d[N];
    10. queue<int> q;
    11. void topsort()
    12. {
    13. for(int i = 1;i <= n; i ++ )
    14. {
    15. if(!d[i])
    16. {
    17. q.push(i);
    18. a[i] = len[i];
    19. }
    20. }
    21. while(q.size())
    22. {
    23. int t = q.front();
    24. q.pop();
    25. for(int i = 0; i < e[t].size(); i ++ )
    26. {
    27. int j = e[t][i];
    28. d[j] --;
    29. if(!d[j])
    30. {
    31. q.push(j);
    32. }
    33. a[j] = max(a[j], a[t] + len[j]); // 并行的杂务算出最大覆盖的时间
    34. }
    35. }
    36. }
    37. int main()
    38. {
    39. cin >> n;
    40. for(int i = 0; i < n; i ++ )
    41. {
    42. int a, b;
    43. cin >> a;
    44. cin >> len[a];
    45. while(scanf("%d", &b))
    46. {
    47. if(!b) break;
    48. e[b].push_back(a);
    49. d[a] ++;
    50. }
    51. }
    52. topsort();
    53. for(int i = 1; i <= n; i ++ )
    54. {
    55. ans = max(a[i], ans);
    56. }
    57. cout << ans << endl;
    58. return 0;
    59. }

    例三:P1807 最长路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

    也是记忆化+拓扑

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N = 5010;
    6. struct edges
    7. {
    8. int a, b, w;
    9. };
    10. vector e[N];
    11. int n, m;
    12. int ind[N];
    13. queue<int> q;
    14. int f[N];
    15. bool st[N];
    16. void toposort()
    17. {
    18. for(int i = 1; i <= n; i ++ )
    19. {
    20. if(!ind[i])
    21. {
    22. q.push(i);
    23. }
    24. }
    25. while(q.size())
    26. {
    27. int t = q.front();
    28. q.pop();
    29. for(int i = 0; i < e[t].size(); i ++ )
    30. {
    31. int j = e[t][i].b;
    32. ind[j] --;
    33. if(!ind[j])
    34. {
    35. q.push(j);
    36. }
    37. if(st[t])
    38. {
    39. st[j] = true;
    40. f[j] = max(f[j], f[t] + e[t][i].w);
    41. }
    42. }
    43. }
    44. }
    45. int main()
    46. {
    47. cin >> n >> m;
    48. for(int i = 0; i < m; i ++ )
    49. {
    50. int a, b, w;
    51. cin >> a >> b >> w;
    52. e[a].push_back((edges){a, b, w});
    53. ind[b] ++;
    54. }
    55. st[1] = true;
    56. f[n] = -1; // 如果说无法到达 就输出-1
    57. toposort();
    58. cout << f[n] << endl;
    59. return 0;
    60. }

    toposort的应用还有很多,比如说在动态规划中,但是我还没学

  • 相关阅读:
    DRCNN:超越高斯去噪:深度CNN图像去噪的残差学习
    使用接口根据关键词取视频列表详情
    工程材料知识点总结(全)
    BOM体系学习
    工业智能网关BL110应用之三十九:LAN口如何配置采集Modbus协议设备S475
    基于PHP+MySQL的家教平台
    Mycat与ShardingSphere如何选择(未完待续)
    力扣——盛最多水的容器
    Android简易音乐重构MVVM Java版-新增歌曲播放界面+状态栏黑科技(十七)
    前端练习--W3C导航条
  • 原文地址:https://blog.csdn.net/qq_74593128/article/details/132526512