图论模板

floyd 算法

template <typename T>
struct Floyd {
  const T INF = std::is_same_v<T, long long> ? 1e18 : 1e9;
  int n;
  std::vector<std::vector<T>> dp;
  Floyd(int n_) : n(n_) {
    dp.resize(n + 1);
    for (auto& row : dp) {
      row.resize(n + 1, INF);
    }
    for (int i = 1; i <= n; i++) {
      dp[i][i] = 0;
    }
  }
  void calFloyd() {
    for (int k = 1; k <= n; k++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          dp[i][j] = std::min(dp[i][j], dp[i][k] + dp[k][j]);
        }
      }
    }
  }
  std::vector<std::vector<T>>& getDp() { return dp; }
};

kruskal 算法

#include <algorithm>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <vector>

// ^ +DEBUG.*\n
// #define DEBUG

struct Edge {
  int a, b, w;
  bool operator<(const Edge& T) const { return w < T.w; }
};

class Dsu {
 public:
  std::vector<int> p;
  Dsu(int n) {
    p.resize(n + 1);
    for (int i = 1; i <= n; i++) {
      p[i] = i;
    }
  }
  int find(int x) {
    if (p[x] != x) {
      p[x] = find(p[x]);
    }
    return p[x];
  }
};
class Kruskal {
 public:
  static const int INF = 1e9;
  int n;  // 图的点数
  Kruskal(int n_) : n(n_) {}
  int kruskal(std::vector<Edge>& edges, Dsu& dsu) {
    std::sort(edges.begin(), edges.end());
    int res = 0;
    int cnt = 0;
    for (auto& edge : edges) {
      int A = dsu.find(edge.a);
      int B = dsu.find(edge.b);
      if (A != B) {
        dsu.p[A] = B;
        res += edge.w;
        cnt++;
      }
    }
    if (cnt == n - 1) {
      return res;
    }
    return INF;
  }
};

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
#ifdef DEBUG
  std::ifstream inputFile("in.txt");
  if (inputFile.is_open()) {
    std::cin.rdbuf(inputFile.rdbuf());
  }
#endif

  int n, m;
  std::cin >> n >> m;
  std::vector<Edge> edges(m);
  for (int i = 0; i < m; i++) {
    int a, b, w;
    std::cin >> a >> b >> w;
    edges[i] = {a, b, w};
  }
  Dsu dsu(n);

  Kruskal kr(n);
  int res = kr.kruskal(edges, dsu);
  if (res != Kruskal::INF) {
    std::cout << res << std::endl;
  } else {
    std::cout << "impossible" << std::endl;
  }
}

dijkstra算法

#include <algorithm>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <vector>

// ^ +DEBUG.*\n
// #define DEBUG

class Dijkstra {
 public:
  static const int INF;
  int n;
  std::vector<std::vector<int>> g;
  std::vector<bool> st;
  std::vector<int> dist;
  Dijkstra(int n_) : n(n_) {
    g = std::vector<std::vector<int>>(n + 1, std::vector<int>(n + 1, INF));
    st.resize(n + 1);
    dist = std::vector<int>(n + 1, INF);
  }

  int dijkstra() {
    dist[1] = 0;
    for (int i = 0; i < n - 1; i++) {
      int id = -1;
      for (int j = 1; j <= n; j++) {
        if (!st[j] && (id == -1 || dist[id] > dist[j])) {
          id = j;
        }
      }
      st[id] = true;
      for (int j = 1; j <= n; j++) {
        dist[j] = std::min(dist[j], dist[id] + g[id][j]);
      }
    }
    if (dist[n] != INF) {
      return dist[n];
    }
    return INF;
  }
};
const int Dijkstra::INF = 1e9;  // 由于在构造函数使用了INF,故此处INF必须在类外定义

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
#ifdef DEBUG
  std::ifstream inputFile("in.txt");
  if (inputFile.is_open()) {
    std::cin.rdbuf(inputFile.rdbuf());
  }
#endif
  int n, m;
  std::cin >> n >> m;
  Dijkstra dij(n);
  while (m--) {
    int x, y, z;
    std::cin >> x >> y >> z;
    dij.g[x][y] = std::min(dij.g[x][y], z);
  }
  int res = dij.dijkstra();
  if (res != Dijkstra::INF) {
    std::cout << res << std::endl;
  } else {
    std::cout << -1 << std::endl;
  }
}

堆优化的dijkstra算法

#include <algorithm>
#include <deque>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <vector>

// ^ +DEBUG.*\n
// #define DEBUG

class Graph {
 public:
  struct Edge {
    int to;
    int w;
  };
  int n;
  std::vector<std::vector<Edge>> adj;
  Graph(int n_) : n(n_), adj(n_ + 1) {}  // 这样
  void add(int x, int y, int z) { adj[x].push_back({y, z}); }
};

class Dijkstra {
 public:
  static const int INF;
  using pii = std::pair<int, int>;

  int n;
  std::vector<int> dist;
  std::priority_queue<pii, std::vector<pii>, std::greater<pii>> heap;
  std::vector<bool> st;

  Dijkstra(int n_) : n(n_), dist(n + 1, INF), st(n + 1, false) {}

  int dijkstra(Graph& g) {
    dist[1] = 0;
    heap.push({0, 1});
    while (!heap.empty()) {
      auto [d, id] = heap.top();  // 结构化绑定
      heap.pop();

      if (st[id]) continue;
      st[id] = true;

      for (const auto& edge : g.adj[id]) {
        if (dist[edge.to] > d + edge.w) {
          dist[edge.to] = d + edge.w;
          heap.push({dist[edge.to], edge.to});
        }
      }
    }
    return dist[n] != INF ? dist[n] : -1;
  }
};
const int Dijkstra::INF = 1e9;

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
#ifdef DEBUG
  std::ifstream inputFile("in.txt");
  if (inputFile.is_open()) {
    std::cin.rdbuf(inputFile.rdbuf());
  }
#endif
  int n, m;
  std::cin >> n >> m;
  Graph g(n);
  Dijkstra dij(n);
  while (m--) {
    int x, y, z;
    std::cin >> x >> y >> z;
    g.add(x, y, z);
  }
  std::cout << dij.dijkstra(g) << '\n';
}
posted @   hacker_dvd  阅读(5)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示