最小生成樹
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;
}