• 【算法笔记自学】第 10 章 提高篇(4)——图算法专题


    10.1图的定义和相关术语

    1. #include
    2. const int MAXN = 100;
    3. int degree[MAXN] = {0};
    4. int main() {
    5. int n, m, u, v;
    6. scanf("%d%d", &n, &m);
    7. for (int j = 0; j < m; j++) {
    8. scanf("%d%d", &u, &v);
    9. degree[u]++;
    10. degree[v]++;
    11. }
    12. for (int i = 0; i < n; i++) {
    13. printf("%d", degree[i]);
    14. if (i < n - 1) {
    15. printf(" ");
    16. }
    17. }
    18. return 0;
    19. }

    1. #include
    2. const int MAXN = 100;
    3. int inDegree[MAXN] = {0};
    4. int outDegree[MAXN] = {0};
    5. int main() {
    6. int n, m, u, v;
    7. scanf("%d%d", &n, &m);
    8. for (int j = 0; j < m; j++) {
    9. scanf("%d%d", &u, &v);
    10. outDegree[u]++;
    11. inDegree[v]++;
    12. }
    13. for (int i = 0; i < n; i++) {
    14. printf("%d %d\n", inDegree[i], outDegree[i]);
    15. }
    16. return 0;
    17. }

    10.2图的存储

    1. #include
    2. #include
    3. const int MAXN = 100;
    4. int G[MAXN][MAXN];
    5. int main() {
    6. memset(G, 0, sizeof(G));
    7. int n, m, u, v;
    8. scanf("%d%d", &n, &m);
    9. for (int i = 0; i < m; i++) {
    10. scanf("%d%d", &u, &v);
    11. G[u][v] = G[v][u] = 1;
    12. }
    13. for (int i = 0; i < n; i++) {
    14. for (int j = 0; j < n; j++) {
    15. printf("%d", G[i][j]);
    16. printf(j < n - 1 ? " " : "\n");
    17. }
    18. }
    19. return 0;
    20. }

    1. #include
    2. #include
    3. const int MAXN = 100;
    4. int G[MAXN][MAXN];
    5. int main() {
    6. memset(G, 0, sizeof(G));
    7. int n, m, u, v;
    8. scanf("%d%d", &n, &m);
    9. for (int i = 0; i < m; i++) {
    10. scanf("%d%d", &u, &v);
    11. G[u][v] = 1;
    12. }
    13. for (int i = 0; i < n; i++) {
    14. for (int j = 0; j < n; j++) {
    15. printf("%d", G[i][j]);
    16. printf(j < n - 1 ? " " : "\n");
    17. }
    18. }
    19. return 0;
    20. }

    1. #include
    2. #include
    3. using namespace std;
    4. const int MAXN = 100;
    5. vector<int> G[MAXN];
    6. int main() {
    7. int n, m, u, v;
    8. scanf("%d%d", &n, &m);
    9. for (int i = 0; i < m; i++) {
    10. scanf("%d%d", &u, &v);
    11. G[u].push_back(v);
    12. G[v].push_back(u);
    13. }
    14. for (int i = 0; i < n; i++) {
    15. printf("%d(%d)", i, (int)G[i].size());
    16. for (int j = 0; j < G[i].size(); j++) {
    17. printf(" %d", G[i][j]);
    18. }
    19. printf("\n");
    20. }
    21. return 0;
    22. }

    1. #include
    2. #include
    3. using namespace std;
    4. const int MAXN = 100;
    5. vector<int> G[MAXN];
    6. int main() {
    7. int n, m, u, v;
    8. scanf("%d%d", &n, &m);
    9. for (int i = 0; i < m; i++) {
    10. scanf("%d%d", &u, &v);
    11. G[u].push_back(v);
    12. }
    13. for (int i = 0; i < n; i++) {
    14. printf("%d(%d)", i, (int)G[i].size());
    15. for (int j = 0; j < G[i].size(); j++) {
    16. printf(" %d", G[i][j]);
    17. }
    18. printf("\n");
    19. }
    20. return 0;
    21. }

    10.3图的遍历

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int MAXN = 100;
    6. vector<int> G[MAXN];
    7. bool vis[MAXN];
    8. void DFS(int u) {
    9. vis[u] = true;
    10. for (int i = 0; i < G[u].size(); i++) {
    11. int v = G[u][i];
    12. if (!vis[v]) {
    13. DFS(v);
    14. }
    15. }
    16. }
    17. int main() {
    18. memset(vis, false, sizeof(vis));
    19. int n, m, u, v;
    20. scanf("%d%d", &n, &m);
    21. for (int i = 0; i < m; i++) {
    22. scanf("%d%d", &u, &v);
    23. G[u].push_back(v);
    24. G[v].push_back(u);
    25. }
    26. int blockCount = 0;
    27. for (int i = 0; i < n; i++) {
    28. if (!vis[i]) {
    29. DFS(i);
    30. blockCount++;
    31. }
    32. }
    33. printf("%d", blockCount);
    34. return 0;
    35. }

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int MAXN = 100;
    6. vector<int> G[MAXN];
    7. bool vis[MAXN];
    8. void DFS(int u) {
    9. vis[u] = true;
    10. for (int i = 0; i < G[u].size(); i++) {
    11. int v = G[u][i];
    12. if (!vis[v]) {
    13. DFS(v);
    14. }
    15. }
    16. }
    17. int main() {
    18. memset(vis, false, sizeof(vis));
    19. int n, m, u, v;
    20. scanf("%d%d", &n, &m);
    21. for (int i = 0; i < m; i++) {
    22. scanf("%d%d", &u, &v);
    23. G[u].push_back(v);
    24. G[v].push_back(u);
    25. }
    26. int blockCount = 0;
    27. for (int i = 0; i < n; i++) {
    28. if (!vis[i]) {
    29. DFS(i);
    30. blockCount++;
    31. }
    32. }
    33. printf(blockCount == 1 ? "Yes" : "No");
    34. return 0;
    35. }

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int MAXN = 100;
    6. vector<int> G[MAXN];
    7. int vis[MAXN];
    8. bool isCyclic(int u) {
    9. vis[u] = 0;
    10. for (int i = 0; i < G[u].size(); i++) {
    11. int v = G[u][i];
    12. if (vis[v] == -1 && isCyclic(v)) {
    13. return true;
    14. } else if (vis[v] == 0) {
    15. return true;
    16. }
    17. }
    18. vis[u] = 1;
    19. return false;
    20. }
    21. int main() {
    22. memset(vis, -1, sizeof(vis));
    23. int n, m, u, v;
    24. scanf("%d%d", &n, &m);
    25. for (int i = 0; i < m; i++) {
    26. scanf("%d%d", &u, &v);
    27. G[u].push_back(v);
    28. }
    29. int isCyclicResult = false;
    30. for (int i = 0; i < n; i++) {
    31. if (vis[i] == -1 && isCyclic(i)) {
    32. isCyclicResult = true;
    33. }
    34. if (isCyclicResult) {
    35. break;
    36. }
    37. }
    38. printf(isCyclicResult ? "Yes" : "No");
    39. return 0;
    40. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. int weight[MAXN];
    8. vector<int> G[MAXN];
    9. bool vis[MAXN];
    10. int DFS(int u) {
    11. vis[u] = true;
    12. int weightSum = weight[u];
    13. for (int i = 0; i < G[u].size(); i++) {
    14. int v = G[u][i];
    15. if (!vis[v]) {
    16. weightSum += DFS(v);
    17. }
    18. }
    19. return weightSum;
    20. }
    21. int main() {
    22. memset(vis, false, sizeof(vis));
    23. int n, m, u, v;
    24. scanf("%d%d", &n, &m);
    25. for (int i = 0; i < n; i++) {
    26. scanf("%d", &weight[i]);
    27. }
    28. for (int i = 0; i < m; i++) {
    29. scanf("%d%d", &u, &v);
    30. G[u].push_back(v);
    31. G[v].push_back(u);
    32. }
    33. int maxWeightSum = 0;
    34. for (int i = 0; i < n; i++) {
    35. if (!vis[i]) {
    36. maxWeightSum = max(maxWeightSum, DFS(i));
    37. }
    38. }
    39. printf("%d", maxWeightSum);
    40. return 0;
    41. }

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int MAXN = 100;
    6. vector<int> G[MAXN];
    7. bool inQueue[MAXN] = {false};
    8. int layers[MAXN];
    9. void BFS(int s) {
    10. queue<int> q;
    11. q.push(s);
    12. inQueue[s] = true;
    13. int layer = 0;
    14. while (!q.empty()) {
    15. int cnt = q.size();
    16. for (int i = 0; i < cnt; i++) {
    17. int front = q.front();
    18. q.pop();
    19. layers[front] = layer;
    20. for (int j = 0; j < G[front].size(); j++) {
    21. int v = G[front][j];
    22. if (!inQueue[v]) {
    23. q.push(v);
    24. inQueue[v] = true;
    25. }
    26. }
    27. }
    28. layer++;
    29. }
    30. }
    31. int main() {
    32. int n, m, start, u, v;
    33. scanf("%d%d%d", &n, &m, &start);
    34. for (int i = 0; i < m; i++) {
    35. scanf("%d%d", &u, &v);
    36. G[u].push_back(v);
    37. G[v].push_back(u);
    38. }
    39. BFS(start);
    40. for (int i = 0; i < n; i++) {
    41. printf("%d", layers[i]);
    42. if (i < n - 1) {
    43. printf(" ");
    44. }
    45. }
    46. return 0;
    47. }

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int MAXN = 100;
    6. vector<int> G[MAXN];
    7. bool inQueue[MAXN] = {false};
    8. int BFS(int s, int maxLayer) {
    9. queue<int> q;
    10. q.push(s);
    11. inQueue[s] = true;
    12. int layer = 0;
    13. int vertexCount = 0;
    14. while (!q.empty() && layer <= maxLayer) {
    15. int cnt = q.size();
    16. vertexCount += cnt;
    17. for (int i = 0; i < cnt; i++) {
    18. int front = q.front();
    19. q.pop();
    20. for (int j = 0; j < G[front].size(); j++) {
    21. int v = G[front][j];
    22. if (!inQueue[v]) {
    23. q.push(v);
    24. inQueue[v] = true;
    25. }
    26. }
    27. }
    28. layer++;
    29. }
    30. return vertexCount;
    31. }
    32. int main() {
    33. int n, m, start, maxLayer, u, v;
    34. scanf("%d%d%d%d", &n, &m, &start, &maxLayer);
    35. for (int i = 0; i < m; i++) {
    36. scanf("%d%d", &u, &v);
    37. G[u].push_back(v);
    38. }
    39. int vertexCount = BFS(start, maxLayer);
    40. printf("%d", vertexCount);
    41. return 0;
    42. }

    10.4最短路径

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis;
    10. Edge(int _v, int _dis) {
    11. v = _v, dis = _dis;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN];
    16. bool vis[MAXN];
    17. void dijkstra(int n, int s) {
    18. fill(d, d + MAXN, INF);
    19. memset(vis, false, sizeof(vis));
    20. d[s] = 0;
    21. for (int i = 0; i < n; i++) {
    22. int u = -1, minDis = INF;
    23. for (int j = 0; j < n; j++) {
    24. if (!vis[j] && d[j] < minDis) {
    25. u = j;
    26. minDis = d[j];
    27. }
    28. }
    29. if (u == -1) {
    30. return;
    31. }
    32. vis[u] = true;
    33. for (int j = 0; j < G[u].size(); j++) {
    34. int v = G[u][j].v;
    35. int dis = G[u][j].dis;
    36. if (!vis[v] && d[u] + dis < d[v]) {
    37. d[v] = d[u] + dis;
    38. }
    39. }
    40. }
    41. }
    42. int main() {
    43. int n, m, s, t;
    44. scanf("%d%d%d%d", &n, &m, &s, &t);
    45. int u, v, w;
    46. for (int i = 0; i < m; i++) {
    47. scanf("%d%d%d", &u, &v, &w);
    48. G[u].push_back(Edge(v, w));
    49. G[v].push_back(Edge(u, w));
    50. }
    51. dijkstra(n, s);
    52. if (d[t] == INF) {
    53. printf("-1");
    54. } else {
    55. printf("%d", d[t]);
    56. }
    57. return 0;
    58. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis;
    10. Edge(int _v, int _dis) {
    11. v = _v, dis = _dis;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN];
    16. bool vis[MAXN];
    17. void dijkstra(int n, int s) {
    18. fill(d, d + MAXN, INF);
    19. memset(vis, false, sizeof(vis));
    20. d[s] = 0;
    21. for (int i = 0; i < n; i++) {
    22. int u = -1, minDis = INF;
    23. for (int j = 0; j < n; j++) {
    24. if (!vis[j] && d[j] < minDis) {
    25. u = j;
    26. minDis = d[j];
    27. }
    28. }
    29. if (u == -1) {
    30. return;
    31. }
    32. vis[u] = true;
    33. for (int j = 0; j < G[u].size(); j++) {
    34. int v = G[u][j].v;
    35. int dis = G[u][j].dis;
    36. if (!vis[v] && d[u] + dis < d[v]) {
    37. d[v] = d[u] + dis;
    38. }
    39. }
    40. }
    41. }
    42. int main() {
    43. int n, m, s;
    44. scanf("%d%d%d", &n, &m, &s);
    45. int u, v, w;
    46. for (int i = 0; i < m; i++) {
    47. scanf("%d%d%d", &u, &v, &w);
    48. G[u].push_back(Edge(v, w));
    49. G[v].push_back(Edge(u, w));
    50. }
    51. dijkstra(n, s);
    52. for (int i = 0; i < n; i++) {
    53. if (d[i] == INF) {
    54. printf("-1");
    55. } else {
    56. printf("%d", d[i]);
    57. }
    58. if (i < n - 1) {
    59. printf(" ");
    60. }
    61. }
    62. return 0;
    63. }

     

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis, cost;
    10. Edge(int _v, int _dis, int _cost) {
    11. v = _v, dis = _dis, cost = _cost;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN], c[MAXN];
    16. bool vis[MAXN];
    17. void dijkstra(int n, int s) {
    18. fill(d, d + MAXN, INF);
    19. fill(c, c + MAXN, INF);
    20. memset(vis, false, sizeof(vis));
    21. d[s] = 0;
    22. c[s] = 0;
    23. for (int i = 0; i < n; i++) {
    24. int u = -1, minDis = INF;
    25. for (int j = 0; j < n; j++) {
    26. if (!vis[j] && d[j] < minDis) {
    27. u = j;
    28. minDis = d[j];
    29. }
    30. }
    31. if (u == -1) {
    32. return;
    33. }
    34. vis[u] = true;
    35. for (int j = 0; j < G[u].size(); j++) {
    36. int v = G[u][j].v;
    37. int dis = G[u][j].dis;
    38. int cost = G[u][j].cost;
    39. if (!vis[v]) {
    40. if (d[u] + dis < d[v]) {
    41. d[v] = d[u] + dis;
    42. c[v] = c[u] + cost;
    43. } else if (d[u] + dis == d[v] && c[u] + cost < c[v]) {
    44. c[v] = c[u] + cost;
    45. }
    46. }
    47. }
    48. }
    49. }
    50. int main() {
    51. int n, m, s, t;
    52. scanf("%d%d%d%d", &n, &m, &s, &t);
    53. int u, v, dis, cost;
    54. for (int i = 0; i < m; i++) {
    55. scanf("%d%d%d%d", &u, &v, &dis, &cost);
    56. G[u].push_back(Edge(v, dis, cost));
    57. G[v].push_back(Edge(u, dis, cost));
    58. }
    59. dijkstra(n, s);
    60. printf("%d %d", d[t], c[t]);
    61. return 0;
    62. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis;
    10. Edge(int _v, int _dis) {
    11. v = _v, dis = _dis;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN], pathCount[MAXN];
    16. bool vis[MAXN];
    17. void dijkstra(int n, int s) {
    18. fill(d, d + MAXN, INF);
    19. memset(pathCount, 0, sizeof(pathCount));
    20. memset(vis, false, sizeof(vis));
    21. d[s] = 0;
    22. pathCount[s] = 1;
    23. for (int i = 0; i < n; i++) {
    24. int u = -1, minDis = INF;
    25. for (int j = 0; j < n; j++) {
    26. if (!vis[j] && d[j] < minDis) {
    27. u = j;
    28. minDis = d[j];
    29. }
    30. }
    31. if (u == -1) {
    32. return;
    33. }
    34. vis[u] = true;
    35. for (int j = 0; j < G[u].size(); j++) {
    36. int v = G[u][j].v;
    37. int dis = G[u][j].dis;
    38. if (!vis[v]) {
    39. if (d[u] + dis < d[v]) {
    40. d[v] = d[u] + dis;
    41. pathCount[v] = pathCount[u];
    42. } else if (d[u] + dis == d[v]) {
    43. pathCount[v] += pathCount[u];
    44. }
    45. }
    46. }
    47. }
    48. }
    49. int main() {
    50. int n, m, s, t;
    51. scanf("%d%d%d%d", &n, &m, &s, &t);
    52. int u, v, w;
    53. for (int i = 0; i < m; i++) {
    54. scanf("%d%d%d", &u, &v, &w);
    55. G[u].push_back(Edge(v, w));
    56. G[v].push_back(Edge(u, w));
    57. }
    58. dijkstra(n, s);
    59. printf("%d %d", d[t], pathCount[t]);
    60. return 0;
    61. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis;
    10. Edge(int _v, int _dis) {
    11. v = _v, dis = _dis;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN], pre[MAXN];
    16. bool vis[MAXN];
    17. void dijkstra(int n, int s) {
    18. fill(d, d + MAXN, INF);
    19. memset(pre, -1, sizeof(pre));
    20. memset(vis, false, sizeof(vis));
    21. d[s] = 0;
    22. for (int i = 0; i < n; i++) {
    23. int u = -1, minDis = INF;
    24. for (int j = 0; j < n; j++) {
    25. if (!vis[j] && d[j] < minDis) {
    26. u = j;
    27. minDis = d[j];
    28. }
    29. }
    30. if (u == -1) {
    31. return;
    32. }
    33. vis[u] = true;
    34. for (int j = 0; j < G[u].size(); j++) {
    35. int v = G[u][j].v;
    36. int dis = G[u][j].dis;
    37. if (!vis[v] && d[u] + dis < d[v]) {
    38. d[v] = d[u] + dis;
    39. pre[v] = u;
    40. }
    41. }
    42. }
    43. }
    44. vector<int> path;
    45. void DFS(int v, int s) {
    46. if (v == s) {
    47. path.push_back(v);
    48. return;
    49. }
    50. DFS(pre[v], s);
    51. path.push_back(v);
    52. }
    53. int main() {
    54. int n, m, s, t;
    55. scanf("%d%d%d%d", &n, &m, &s, &t);
    56. int u, v, w;
    57. for (int i = 0; i < m; i++) {
    58. scanf("%d%d%d", &u, &v, &w);
    59. G[u].push_back(Edge(v, w));
    60. G[v].push_back(Edge(u, w));
    61. }
    62. dijkstra(n, s);
    63. DFS(t, s);
    64. printf("%d ", d[t]);
    65. for (int i = 0; i < path.size(); i++) {
    66. printf("%d", path[i]);
    67. if (i < (int)path.size() - 1) {
    68. printf("->");
    69. }
    70. }
    71. return 0;
    72. }

    1. #include
    2. #include
    3. using namespace std;
    4. const int MAXN = 50;
    5. const int INF = 1e9;
    6. int d[MAXN][MAXN];
    7. void floyd(int n) {
    8. for (int k = 0; k < n; k++) {
    9. for (int i = 0; i < n; i++) {
    10. for (int j = 0; j < n; j++) {
    11. if (d[i][k] != INF && d[k][j] != INF && d[i][k] + d[k][j] < d[i][j]) {
    12. d[i][j] = d[i][k] + d[k][j];
    13. }
    14. }
    15. }
    16. }
    17. }
    18. int main() {
    19. int n, m;
    20. scanf("%d%d", &n, &m);
    21. fill(d[0], d[0] + MAXN * MAXN, INF);
    22. for (int i = 0; i < n; i++) {
    23. d[i][i] = 0;
    24. }
    25. int u, v, w;
    26. for (int i = 0; i < m; i++) {
    27. scanf("%d%d%d", &u, &v, &w);
    28. d[u][v] = d[v][u] = w;
    29. }
    30. floyd(n);
    31. for (int i = 0; i < n; i++) {
    32. for (int j = 0; j < n; j++) {
    33. if (d[i][j] == INF) {
    34. printf("-1");
    35. } else {
    36. printf("%d", d[i][j]);
    37. }
    38. if (j < n - 1) {
    39. printf(" ");
    40. }
    41. }
    42. printf("\n");
    43. }
    44. return 0;
    45. }

    10.5最小生成树

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 500;
    7. const int INF = 1e9;
    8. struct Edge {
    9. int v, dis;
    10. Edge(int _v, int _dis) {
    11. v = _v, dis = _dis;
    12. }
    13. };
    14. vector G[MAXN];
    15. int d[MAXN];
    16. bool vis[MAXN];
    17. int prim(int n) {
    18. fill(d, d + MAXN, INF);
    19. memset(vis, false, sizeof(vis));
    20. d[0] = 0;
    21. int weightSum = 0;
    22. for (int i = 0; i < n; i++) {
    23. int u = -1, minDis = INF;
    24. for (int j = 0; j < n; j++) {
    25. if (!vis[j] && d[j] < minDis) {
    26. u = j;
    27. minDis = d[j];
    28. }
    29. }
    30. if (u == -1) {
    31. return -1;
    32. }
    33. vis[u] = true;
    34. weightSum += d[u];
    35. for (int j = 0; j < G[u].size(); j++) {
    36. int v = G[u][j].v;
    37. int dis = G[u][j].dis;
    38. if (!vis[v] && dis < d[v]) {
    39. d[v] = dis;
    40. }
    41. }
    42. }
    43. return weightSum;
    44. }
    45. int main() {
    46. int n, m;
    47. scanf("%d%d", &n, &m);
    48. int u, v, w;
    49. for (int i = 0; i < m; i++) {
    50. scanf("%d%d%d", &u, &v, &w);
    51. G[u].push_back(Edge(v, w));
    52. G[v].push_back(Edge(u, w));
    53. }
    54. int weightSum = prim(n);
    55. printf("%d", weightSum);
    56. return 0;
    57. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 10000;
    7. struct Edge {
    8. int u, v, w;
    9. Edge(int _u, int _v, int _w) {
    10. u = _u, v = _v, w = _w;
    11. }
    12. };
    13. vector edges;
    14. bool cmp(Edge a, Edge b) {
    15. return a.w < b.w;
    16. }
    17. int father[MAXN];
    18. int findFather(int x) {
    19. int xCopy = x;
    20. while (father[x] != x) {
    21. x = father[x];
    22. }
    23. int root = x;
    24. x = xCopy;
    25. while (father[x] != x) {
    26. int fatherX = father[x];
    27. father[x] = root;
    28. x = fatherX;
    29. }
    30. return root;
    31. }
    32. int kruskal(int n, int m) {
    33. for (int i = 0; i < n; i++) {
    34. father[i] = i;
    35. }
    36. int weightSum = 0, edgeCount = 0;
    37. sort(edges.begin(), edges.end(), cmp);
    38. for (int i = 0; i < m; i++) {
    39. int faU = findFather(edges[i].u);
    40. int faV = findFather(edges[i].v);
    41. if (faU != faV) {
    42. father[faU] = faV;
    43. weightSum += edges[i].w;
    44. edgeCount++;
    45. }
    46. if (edgeCount == n - 1) {
    47. break;
    48. }
    49. }
    50. if (edgeCount != n - 1) {
    51. return -1;
    52. } else {
    53. return weightSum;
    54. }
    55. }
    56. int main() {
    57. int n, m;
    58. scanf("%d%d", &n, &m);
    59. int u, v, w;
    60. for (int i = 0; i < m; i++) {
    61. scanf("%d%d%d", &u, &v, &w);
    62. edges.push_back(Edge(u, v, w));
    63. }
    64. int weightSum = kruskal(n, m);
    65. printf("%d", weightSum);
    66. return 0;
    67. }

    10.6拓扑排序

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. vector<int> G[MAXN];
    8. int inDegree[MAXN];
    9. vector<int> topoOrder;
    10. void topoSort(int n) {
    11. priority_queue<int, vector<int>, greater<int> > q;
    12. for (int i = 0; i < n; i++) {
    13. if (inDegree[i] == 0) {
    14. q.push(i);
    15. }
    16. }
    17. while (!q.empty()) {
    18. int u = q.top();
    19. q.pop();
    20. topoOrder.push_back(u);
    21. for (int i = 0; i < G[u].size(); i++) {
    22. int v = G[u][i];
    23. inDegree[v]--;
    24. if (inDegree[v] == 0) {
    25. q.push(v);
    26. }
    27. }
    28. G[u].clear();
    29. }
    30. }
    31. int main() {
    32. int n, m;
    33. scanf("%d%d", &n, &m);
    34. int u, v;
    35. for (int i = 0; i < m; i++) {
    36. scanf("%d%d", &u, &v);
    37. G[u].push_back(v);
    38. inDegree[v]++;
    39. }
    40. topoSort(n);
    41. for (int i = 0; i < topoOrder.size(); i++) {
    42. printf("%d", topoOrder[i]);
    43. if (i < (int)topoOrder.size() - 1) {
    44. printf(" ");
    45. }
    46. }
    47. return 0;
    48. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. vector<int> G[MAXN];
    8. int inDegree[MAXN];
    9. bool topoSort(int n) {
    10. int vertexCount = 0;
    11. priority_queue<int, vector<int>, greater<int> > q;
    12. for (int i = 0; i < n; i++) {
    13. if (inDegree[i] == 0) {
    14. q.push(i);
    15. }
    16. }
    17. while (!q.empty()) {
    18. int u = q.top();
    19. q.pop();
    20. for (int i = 0; i < G[u].size(); i++) {
    21. int v = G[u][i];
    22. inDegree[v]--;
    23. if (inDegree[v] == 0) {
    24. q.push(v);
    25. }
    26. }
    27. G[u].clear();
    28. vertexCount++;
    29. }
    30. return vertexCount == n;
    31. }
    32. int main() {
    33. int n, m;
    34. scanf("%d%d", &n, &m);
    35. int u, v;
    36. for (int i = 0; i < m; i++) {
    37. scanf("%d%d", &u, &v);
    38. G[u].push_back(v);
    39. inDegree[v]++;
    40. }
    41. printf(topoSort(n) ? "Yes" : "No");
    42. return 0;
    43. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int MAXN = 100;
    7. vector<int> G[MAXN];
    8. int inDegree[MAXN];
    9. vector<int> topoOrder;
    10. int topoSort(int n) {
    11. int vertexCount = 0;
    12. priority_queue<int, vector<int>, greater<int> > q;
    13. for (int i = 0; i < n; i++) {
    14. if (inDegree[i] == 0) {
    15. q.push(i);
    16. }
    17. }
    18. while (!q.empty()) {
    19. int u = q.top();
    20. q.pop();
    21. topoOrder.push_back(u);
    22. for (int i = 0; i < G[u].size(); i++) {
    23. int v = G[u][i];
    24. inDegree[v]--;
    25. if (inDegree[v] == 0) {
    26. q.push(v);
    27. }
    28. }
    29. G[u].clear();
    30. vertexCount++;
    31. }
    32. return vertexCount;
    33. }
    34. int main() {
    35. int n, m;
    36. scanf("%d%d", &n, &m);
    37. int u, v;
    38. for (int i = 0; i < m; i++) {
    39. scanf("%d%d", &u, &v);
    40. G[u].push_back(v);
    41. inDegree[v]++;
    42. }
    43. int learnCount = topoSort(n);
    44. if (learnCount == n) {
    45. printf("Yes\n");
    46. for (int i = 0; i < topoOrder.size(); i++) {
    47. printf("%d", topoOrder[i]);
    48. if (i < (int)topoOrder.size() - 1) {
    49. printf(" ");
    50. }
    51. }
    52. } else {
    53. printf("No\n%d\n", n - learnCount);
    54. }
    55. return 0;
    56. }

    10.7关键路径

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. const int MAXN = 100;
    8. struct Edge {
    9. int v, w;
    10. Edge(int _v, int _w) {
    11. v = _v, w = _w;
    12. }
    13. };
    14. vector G[MAXN];
    15. int inDegree[MAXN] = {0};
    16. vector<int> topoOrder;
    17. int ve[MAXN], vl[MAXN];
    18. vector<int> activity[MAXN];
    19. bool topoSort(int n) {
    20. priority_queue<int, vector<int>, greater<int> > q;
    21. for (int i = 0; i < n; i++) {
    22. if (inDegree[i] == 0) {
    23. q.push(i);
    24. }
    25. }
    26. while (!q.empty()) {
    27. int u = q.top();
    28. q.pop();
    29. topoOrder.push_back(u);
    30. for (int i = 0; i < G[u].size(); i++) {
    31. int v = G[u][i].v;
    32. inDegree[v]--;
    33. if (inDegree[v] == 0) {
    34. q.push(v);
    35. }
    36. if (ve[u] + G[u][i].w > ve[v]) {
    37. ve[v] = ve[u] + G[u][i].w;
    38. }
    39. }
    40. }
    41. return (int)topoOrder.size() == n;
    42. }
    43. int getCriticalPathLength(int n) {
    44. memset(ve, 0, sizeof(ve));
    45. if (!topoSort(n)) {
    46. return -1;
    47. }
    48. int maxLength = 0;
    49. for(int i = 0; i < n; i++) {
    50. if(ve[i] > maxLength) {
    51. maxLength = ve[i];
    52. }
    53. }
    54. return maxLength;
    55. }
    56. int main() {
    57. int n, m;
    58. scanf("%d%d", &n, &m);
    59. int u, v, w;
    60. for (int i = 0; i < m; i++) {
    61. scanf("%d%d%d", &u, &v, &w);
    62. G[u].push_back(Edge(v, w));
    63. inDegree[v]++;
    64. }
    65. int pathLength = getCriticalPathLength(n);
    66. if (pathLength == -1) {
    67. printf("No");
    68. } else {
    69. printf("Yes\n%d", pathLength);
    70. }
    71. return 0;
    72. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. const int MAXN = 100;
    8. struct Edge {
    9. int v, w;
    10. Edge(int _v, int _w) {
    11. v = _v, w = _w;
    12. }
    13. };
    14. vector G[MAXN];
    15. int inDegree[MAXN] = {0};
    16. vector<int> topoOrder;
    17. int ve[MAXN], vl[MAXN];
    18. vector<int> activity[MAXN];
    19. bool topoSort(int n) {
    20. priority_queue<int, vector<int>, greater<int> > q;
    21. for (int i = 0; i < n; i++) {
    22. if (inDegree[i] == 0) {
    23. q.push(i);
    24. }
    25. }
    26. while (!q.empty()) {
    27. int u = q.top();
    28. q.pop();
    29. topoOrder.push_back(u);
    30. for (int i = 0; i < G[u].size(); i++) {
    31. int v = G[u][i].v;
    32. inDegree[v]--;
    33. if (inDegree[v] == 0) {
    34. q.push(v);
    35. }
    36. if (ve[u] + G[u][i].w > ve[v]) {
    37. ve[v] = ve[u] + G[u][i].w;
    38. }
    39. }
    40. }
    41. return (int)topoOrder.size() == n;
    42. }
    43. int getCriticalPath(int n) {
    44. memset(ve, 0, sizeof(ve));
    45. if (!topoSort(n)) {
    46. return -1;
    47. }
    48. int maxLength = 0;
    49. for(int i = 0; i < n; i++) {
    50. if(ve[i] > maxLength) {
    51. maxLength = ve[i];
    52. }
    53. }
    54. fill(vl, vl + n, maxLength);
    55. for (int i = (int)topoOrder.size() - 1; i >= 0; i--) {
    56. int u = topoOrder[i];
    57. for (int j = 0; j < G[u].size(); j++) {
    58. int v = G[u][j].v;
    59. int w = G[u][j].w;
    60. if (vl[v] - w < vl[u]) {
    61. vl[u] = vl[v] - w;
    62. }
    63. }
    64. }
    65. for (int u = 0; u < n; u++) {
    66. for (int i = 0; i < G[u].size(); i++) {
    67. int v = G[u][i].v;
    68. int w = G[u][i].w;
    69. int e = ve[u], l = vl[v] - w;
    70. if (e == l) {
    71. activity[u].push_back(v);
    72. }
    73. }
    74. }
    75. return maxLength;
    76. }
    77. int main() {
    78. int n, m;
    79. scanf("%d%d", &n, &m);
    80. int u, v, w;
    81. for (int i = 0; i < m; i++) {
    82. scanf("%d%d%d", &u, &v, &w);
    83. G[u].push_back(Edge(v, w));
    84. inDegree[v]++;
    85. }
    86. if (getCriticalPath(n) == -1) {
    87. printf("No");
    88. } else {
    89. printf("Yes\n");
    90. for (int i = 0; i < n; i++) {
    91. sort(activity[i].begin(), activity[i].end());
    92. for (int j = 0; j < activity[i].size(); j++) {
    93. printf("%d %d\n", i, activity[i][j]);
    94. }
    95. }
    96. }
    97. return 0;
    98. }

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. using namespace std;
    7. const int MAXN = 100;
    8. struct Edge {
    9. int v, w;
    10. Edge(int _v, int _w) {
    11. v = _v, w = _w;
    12. }
    13. };
    14. vector G[MAXN];
    15. int inDegree[MAXN] = {0}, inDegreeOrigin[MAXN] = {0};
    16. vector<int> topoOrder;
    17. int ve[MAXN], vl[MAXN];
    18. vector<int> activity[MAXN];
    19. bool topoSort(int n) {
    20. priority_queue<int, vector<int>, greater<int> > q;
    21. for (int i = 0; i < n; i++) {
    22. if (inDegree[i] == 0) {
    23. q.push(i);
    24. }
    25. }
    26. while (!q.empty()) {
    27. int u = q.top();
    28. q.pop();
    29. topoOrder.push_back(u);
    30. for (int i = 0; i < G[u].size(); i++) {
    31. int v = G[u][i].v;
    32. inDegree[v]--;
    33. if (inDegree[v] == 0) {
    34. q.push(v);
    35. }
    36. if (ve[u] + G[u][i].w > ve[v]) {
    37. ve[v] = ve[u] + G[u][i].w;
    38. }
    39. }
    40. }
    41. return (int)topoOrder.size() == n;
    42. }
    43. int getCriticalPath(int n) {
    44. memset(ve, 0, sizeof(ve));
    45. if (!topoSort(n)) {
    46. return -1;
    47. }
    48. int maxLength = 0;
    49. for(int i = 0; i < n; i++) {
    50. if(ve[i] > maxLength) {
    51. maxLength = ve[i];
    52. }
    53. }
    54. fill(vl, vl + n, maxLength);
    55. for (int i = (int)topoOrder.size() - 1; i >= 0; i--) {
    56. int u = topoOrder[i];
    57. for (int j = 0; j < G[u].size(); j++) {
    58. int v = G[u][j].v;
    59. int w = G[u][j].w;
    60. if (vl[v] - w < vl[u]) {
    61. vl[u] = vl[v] - w;
    62. }
    63. }
    64. }
    65. for (int u = 0; u < n; u++) {
    66. for (int i = 0; i < G[u].size(); i++) {
    67. int v = G[u][i].v;
    68. int w = G[u][i].w;
    69. int e = ve[u], l = vl[v] - w;
    70. if (e == l) {
    71. activity[u].push_back(v);
    72. }
    73. }
    74. }
    75. return maxLength;
    76. }
    77. vector<int> criticalPath;
    78. void printCriticalPath(int u) {
    79. if(activity[u].size() == 0) {
    80. criticalPath.push_back(u);
    81. for(int i = 0; i < criticalPath.size(); i++) {
    82. printf("%d", criticalPath[i]);
    83. if(i < criticalPath.size() - 1) {
    84. printf("->");
    85. } else {
    86. printf("\n");
    87. }
    88. }
    89. criticalPath.pop_back();
    90. return;
    91. }
    92. criticalPath.push_back(u);
    93. sort(activity[u].begin(), activity[u].end());
    94. for(int i = 0; i < activity[u].size(); i++) {
    95. printCriticalPath(activity[u][i]);
    96. }
    97. criticalPath.pop_back();
    98. }
    99. int main() {
    100. int n, m;
    101. scanf("%d%d", &n, &m);
    102. int u, v, w;
    103. for (int i = 0; i < m; i++) {
    104. scanf("%d%d%d", &u, &v, &w);
    105. G[u].push_back(Edge(v, w));
    106. inDegree[v]++;
    107. inDegreeOrigin[v]++;
    108. }
    109. if (getCriticalPath(n) == -1) {
    110. printf("No");
    111. } else {
    112. printf("Yes\n");
    113. for(int i = 0; i < n; i++) {
    114. if(inDegreeOrigin[i] == 0 && activity[i].size() != 0) {
    115. printCriticalPath(i);
    116. }
    117. }
    118. }
    119. return 0;
    120. }

  • 相关阅读:
    GPO:部署 ADMX/ADML Template
    debian/ubuntu/windows配置wiregurad内网服务器(包含掉线自启动)
    Numpy数组计算实训
    基于 HBase & Phoenix 构建实时数仓(2)—— HBase 完全分布式安装
    _tkinter.TclError: no display name and no $DISPLAY environment variable 解决
    Python —— OS module
    攻防世界WEB练习区(backup、cookie、disabled_button)
    关于http网络通信数据包封装的过程
    Sqlite查询结果为List<T>
    LeetCode刷题复盘笔记—一文搞懂纯完全背包问题(动态规划系列第十一篇)
  • 原文地址:https://blog.csdn.net/qq_62704693/article/details/140377633