web123456

Summary of graph theory issues

One,shortest pathconcern

1. Single-source shortest path

Depth or breadth-first algorithm that accesses all depth traversal paths or breadth-first paths from the starting point, then there are multiple paths to the end node, and the one with the shortest path weights is the shortest path.

  1. void dfs(int cur, int dst){
  2. if(minPath < dst) return;//The current path is larger than the previous shortest path, so there is no need to go further.
  3. if(cur == n){//critical condition
  4. if(minPath > dst) minPath = dst;
  5. return;
  6. }
  7. else{
  8. int i;
  9. for(i = 1; i <= n; i++){
  10. //Guarantee that paths exist between nodes and have not been accessed, non-existing node paths are set to infinity inf
  11. if(edge[cur][i] != inf && edge[cur][i] != 0 && mark[i] == 0){
  12. mark[i] = 1;
  13. dfs(i, dst+edge[cur][i]);
  14. mark[i] = 0;
  15. }
  16. }
  17. return;
  18. }
  19. }

2、Multi-source shortest path

Floyd-Warshall algorithm, basic idea: at first only allow transit through vertex #1, next only allow transit through vertices #1 and #2 ...... Allow transit through all vertices from 1 to n to constantly and dynamically update the shortest distance between any two points. That is, find the shortest distance from vertex i to vertex j through only the first k points.

  1. //Using Floyd's algorithm
  2. int k; //Join nodes k in turn
  3. for(k = 1; k <= n; k++){
  4. for(i = 1; i <= n; i++){
  5. for(j = 1; j <= n; j++){
  6. //Guarantees that edges exist, that non-existing edge weights are set to infinity inf, and that shorter paths exist
  7. if(edge[i][k] < inf && edge[k][j] < inf && edge[i][j] > edge[i][k] + edge[k][j])
  8. edge[i][j] = edge[i][k] + edge[k][j];
  9. }
  10. }
  11. }

II. Determine if there is a ring in the diagram

Depth or breadth-first algorithms that determine whether duplicate searched nodes are encountered during the search.

Ideas: adjacency table to build a graph, determine whether the graph has a ring, if there is a ring does not satisfy the question

  1. class Solution {
  2. public:
  3. bool dfs(int i,vector<vector<int>>&adjacent,vector<int>&flag){
  4. if(flag[i]==-1) return true; //The current node has already been visited, no need to repeat the search
  5. if(flag[i]==1) return false; //Repeated in one round of dfs, i.e., with rings
  6. flag[i]=1;
  7. for(auto j:adjacent[i]){
  8. if(!dfs(j,adjacent,flag))
  9. return false;
  10. }
  11. flag[i]=-1;
  12. return true;
  13. }
  14. bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
  15. vector<vector<int>>adjacent(numCourses);
  16. vector<int>flag(numCourses);
  17. //Neighbor-joining table construction
  18. for(int i=0;i<prerequisites.size();i++){
  19. adjacent[prerequisites[i][0]].push_back(prerequisites[i][1]);
  20. }
  21. for(int i=0;i<numCourses;i++) {
  22. if(!dfs(i,adjacent,flag))
  23. return false;
  24. }
  25. return true;
  26. }
  27. };

 

III. Concurrent sets

Solving connectivity problems.

  1. class DisjointSetUnion {
  2. private:
  3. //f i.e., save the parent array of the node, rank in order to balance the inserted nodes
  4. vector<int> f, rank;
  5. int n;
  6. public:
  7. //initialization
  8. DisjointSetUnion(int _n) {
  9. n = _n;
  10. (n, 1);
  11. (n);
  12. for (int i = 0; i < n; i++) {
  13. f[i] = i;
  14. }
  15. }
  16. //find
  17. int find(int x) {
  18. return f[x] == x ? x : f[x] = find(f[x]);
  19. }
  20. //parallel operation
  21. void unionSet(int x, int y) {
  22. int fx = find(x), fy = find(y);
  23. if (fx == fy) {
  24. return;
  25. }
  26. //Let the low number of nodes join to the high number of nodes in the concatenation set
  27. if (rank[fx] < rank[fy]) {
  28. swap(fx, fy);
  29. }
  30. rank[fx] += rank[fy];
  31. f[fy] = fx;
  32. }
  33. };

IV. The minimum spanning tree problem

1. Prim (Prim) algorithm

Basic Idea: Primm's algorithm divides the vertices into two classes when finding the minimum spanning tree, one class is already included in the tree during the search (assumed to be class A), and the rest is the other class (assumed to be class B). For a given connected network, all vertices in the starting state are categorized into class B. In finding the minimum spanning tree, any vertex is selected as the starting point and moved from class B to class A. Then the vertex with the smallest weight between the vertices in class B and those in class A is found (all edges between all the vertices in A and B are computed), and is moved from class B to class A, and so on until there are no vertices in class B. The minimum spanning tree is then used as the starting point of the minimum spanning tree. The vertices and edges traveled are the minimum spanning tree of the connected graph.

2. Kruskal (Kruskal) algorithm and parallel checking set

Idea: Sort all distances, then scan and update based on whether the scanned edge is in a connected block.

  1. class DisjointSetUnion {
  2. private:
  3. vector<int> f, rank;
  4. int n;
  5. public:
  6. DisjointSetUnion(int _n) {
  7. n = _n;
  8. (n, 1);
  9. (n);
  10. for (int i = 0; i < n; i++) {
  11. f[i] = i;
  12. }
  13. }
  14. int find(int x) {
  15. return f[x] == x ? x : f[x] = find(f[x]);
  16. }
  17. bool unionSet(int x, int y) {
  18. int fx = find(x), fy = find(y);
  19. if (fx == fy) {
  20. return false;
  21. }
  22. if (rank[fx] < rank[fy]) {
  23. swap(fx, fy);
  24. }
  25. rank[fx] += rank[fy];
  26. f[fy] = fx;
  27. return true;
  28. }
  29. };
  30. struct Edge {
  31. int len, x, y;
  32. Edge(int len, int x, int y) : len(len), x(x), y(y) {
  33. }
  34. };
  35. class Solution {
  36. public:
  37. int minCostConnectPoints(vector<vector<int>>& points) {
  38. auto dist = [&](int x, int y) -> int {
  39. return abs(points[x][0] - points[y][0]) + abs(points[x][1] - points[y][1]);
  40. };
  41. int n = points.size();
  42. DisjointSetUnion dsu(n);
  43. vector<Edge> edges;
  44. for (int i = 0; i < n; i++) {
  45. for (int j = i + 1; j < n; j++) {
  46. edges.emplace_back(dist(i, j), i, j);
  47. }
  48. }
  49. sort((), edges.end(), [](Edge a, Edge b) -> int { return < ; });
  50. int ret = 0, num = 1;
  51. for (auto& [len, x, y] : edges) {
  52. if ((x, y)) {
  53. ret += len;
  54. num++;
  55. if (num == n) {
  56. break;
  57. }
  58. }
  59. }
  60. return ret;
  61. }
  62. };