秘製小模板

GenesisCrystal發表於2024-10-18

最小生成樹

Prim

Code
#include <iostream>
#include <queue>

using namespace std;

const int kMaxN = 1e5 + 1;

int n, m;
vector<pair<int, int>> g[kMaxN];
struct Node {
  int u, w;
  Node (int a, int b) {
    u = a, w = b;
  }
  friend bool operator<(Node a, Node b) {
    return a.w > b.w;
  }
};

auto Prim() {
  priority_queue<Node> q;
  int dis[kMaxN] = {};
  fill(dis + 1, dis + n + 1, 1e9), dis[1] = 0;
  bool f[kMaxN] = {};
  q.push(Node(1, 0));
  while (!q.empty()) {
    Node t = q.top();
    q.pop();
    if (f[t.u]) {
      continue;
    }
    f[t.u] = 1;
    for (pair<int, int> i : g[t.u]) {
      if (dis[i.first] > i.second && !f[i.first]) {
        dis[i.first] = i.second;
        q.push(Node(i.first, dis[i.first]));
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (!f[i]) {
      return (string)"orz";
    }
    ans += dis[i];
  }
  return to_string(ans);
}

int main() {
  cin >> n >> m;
  for (int i = 1, u, v, w; i <= m; i++) {
    cin >> u >> v >> w;
    g[u].push_back({v, w}), g[v].push_back({u, w});
  }
  cout << Prim();
  return 0;
}

Kruskal

Code
#include <iostream>
#include <algorithm>

using namespace std;

const int kMaxN = 2e5 + 1;

struct S{
  int u, v, w;
  friend bool operator <(S a, S b) {
    return a.w < b.w;
  }
  friend istream &operator>>(istream &in, S &a) {
    in >> a.u >> a.v >> a.w;
    return in;
  }
} side[kMaxN];
int n, m, f[kMaxN], ans, c;
int find(int x) {
  return f[x] = f[x] == x ? x : find(f[x]);
}

int main() {
  cin >> n >> m;
  for (int i = 1 ; i <= n; i++) {
    f[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    cin >> side[i];
  }
  sort(side + 1, side + m + 1);
  for (int i = 1; i <= m; i++) {
    if (c == n - 1) {
      break;
    }
    if (find(side[i].u) != find(side[i].v)) {
      c++;
      f[f[side[i].v]] = f[side[i].u];
      find(side[i].v);
      ans += side[i].w;
    }
  }
  cout << (c == n - 1 ? to_string(ans) : "orz");
  return 0;
}

最短路

Dijkstra

Code
#include <iostream>
#include <queue>

using namespace std;
using ll = long long;

const int kMaxN = 1e5 + 1;

int n, m, s, u, v, w, a[kMaxN], dis[kMaxN];
struct node {
  int u, w;
  bool operator<(const node& a) const {
    return w > a.w;
  }
};
vector<node> g[kMaxN];

void D() {
  priority_queue<node> q;
  bool f[kMaxN] = {};
  q.push({s, 0});
  dis[s] = 0;
  while (!q.empty()) {
    int t = q.top().u;
    q.pop();
    if (f[t]) {
      continue;
    }
    f[t] = 1;
    for (auto i : g[t]) {
      if (dis[t] + i.w < dis[i.u]) {
        dis[i.u] = dis[t] + i.w;
        q.push({i.u, dis[i.u]});
      }
    }
  }
}

int main() {
  cin >> n >> m >> s;
  fill(dis + 1, dis + n + 1, 1e9);
  for (int i = 1; i <= m; i++) {
    cin >> u >> v >> w;
    g[u].push_back({v, w});
  }
  D();
  for (int i = 1; i <= n; i++) {
    cout << dis[i] << " ";
  }
  return 0;
}

SPFA(負環)

Code
#include <bits/stdc++.h>

using namespace std;

const int KMaxN = 1e5 + 1;

bool flag;
int sum = 0;
int n, m, s, u, v, w, dis[KMaxN];
struct node {
  int u, w;
  bool operator<(const node& a) const {
    return w > a.w;
  }
};
vector<node> g[KMaxN];

void S() {
  queue<int> q;
  bool f[KMaxN] = {};
  int v[KMaxN] = {};
  q.push(1);
  dis[1] = 0;
  while (!q.empty()) {
    int t = q.front();
    q.pop();
    f[t] = 0;
    for (auto i : g[t]) {
      if (dis[t] + i.w < dis[i.u]) {
        dis[i.u] = dis[t] + i.w;
        if (!f[i.u]) {
          v[t]++;
          if (v[t] > 2 * m) {
            flag = 0;
            return;
          }
          f[i.u] = 1;
          q.push(i.u);
        }
      }
    }
  }
}

int main() {
  int t;
  for (cin >> t; t; t--) {
    for (int i = 1; i <= n; i++) {
      g[i].clear();
      flag = 1;
    }
    cin >> n >> m;
    fill(dis + 1, dis + n + 1, INT_MAX);
    for (int i = 1; i <= m; i++) {
      cin >> u >> v >> w;
      g[u].push_back({v, w});
      if (w >= 0) {
        g[v].push_back({u, w});
      }
    }
    flag = 1;
    S();
    cout << (flag == 0 ? "YES\n" : "NO\n");
  }
  return 0;
}

相關文章