最短路
Floyed 算法
\(O(n^3)\)
模版
| C++ |
|---|
| for (int k = 1 ; k <= n ; k++) {
for (int i = 1 ; i <= n ; i++) {
for (int j = 1 ; j <= n ; j++) {
a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
}
}
}
|
例题
Bellman-Ford 算法
\(O(nm)\)
模版
| C++ |
|---|
| #include <bits/stdc++.h>
using namespace std;
// 2023 OneWan
struct Node {
int to, val;
Node() = default;
Node(int to, int val) : to(to), val(val) {}
};
vector<Node> adj[200005];
int dist[200005];
int n;
void bellman_ford(int s) {
for (int i = 1 ; i <= n ; i++) {
dist[i] = 0x7fffffff;
}
dist[s] = 0;
for (int i = 1 ; i <= n ; i++) {
bool flag = false;
for (int p = 1 ; p <= n ; p++) {
if (dist[p] == 0x7fffffff) {
continue;
}
for (auto &[to, val] : adj[p]) {
if (dist[p] + val < dist[to]) {
dist[to] = dist[p] + val;
flag = true;
}
}
}
if (flag == false) {
break;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int m, s;
cin >> n >> m >> s;
for (int i = 0 ; i < m ; i++) {
int u, v, val;
cin >> u >> v >> val;
adj[u].emplace_back(v, val);
}
bellman_ford(s);
for (int i = 1 ; i <= n ; i++) {
cout << dist[i] << " ";
}
return 0;
}
|
例题
Spfa 算法
\(O(nm)\)
模版
| C++ |
|---|
| #include <bits/stdc++.h>
using namespace std;
// 2023 OneWan
struct Node {
int to, val;
Node() = default;
Node(int to, int val) : to(to), val(val) {}
};
int dist[10005];
bool vis[10005];
vector<Node> adj[10005];
int n;
void spfa(int s) {
for (int i = 1 ; i <= n ; i++) {
dist[i] = 0x7fffffff;
vis[i] = false;
}
queue<int> que;
que.emplace(s);
dist[s] = 0;
vis[s] = true;
while (!que.empty()) {
int p = que.front();
que.pop();
vis[p] = false;
for (auto &[to, val] : adj[p]) {
if (dist[p] + val < dist[to]) {
dist[to] = dist[p] + val;
if (vis[to] == false) {
vis[to] = true;
que.emplace(to);
}
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int m, s;
cin >> n >> m >> s;
for (int i = 0 ; i < m ; i++) {
int u, v, val;
cin >> u >> v >> val;
adj[u].emplace_back(v, val);
}
spfa(s);
for (int i = 1 ; i <= n ; i++) {
cout << dist[i] << " \n"[i == n];
}
return 0;
}
|
例题
Dijkstra 算法
\(O(m\log m)\)
模版
| C++ |
|---|
| #include <bits/stdc++.h>
using namespace std;
// 2023 OneWan
struct Node {
int to, val;
Node() = default;
Node(int to, int val) : to(to), val(val) {}
bool operator<(const auto &x) const {
return val > x.val;
}
};
vector<Node> adj[200005];
int dist[200005];
bool vis[200005];
int n;
void dijkstra(int s) {
for (int i = 1 ; i <= n ; i++) {
dist[i] = 0x7fffffff;
vis[i] = false;
}
dist[s] = 0;
priority_queue<Node> que;
que.emplace(s, 0);
while (!que.empty()) {
auto x = que.top().to;
que.pop();
if (vis[x] == true) {
continue;
}
vis[x] = true;
for (auto &[to, val] : adj[x]) {
if (dist[x] + val < dist[to]) {
dist[to] = dist[x] + val;
que.emplace(to, dist[to]);
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int m, s;
cin >> n >> m >> s;
for (int i = 0 ; i < m ; i++) {
int u, v, val;
cin >> u >> v >> val;
adj[u].emplace_back(v, val);
}
dijkstra(s);
for (int i = 1 ; i <= n ; i++) {
cout << dist[i] << " ";
}
return 0;
}
|
例题
Johnson 全源最短路径算法
\(O(nm\log m)\)
跑一遍 spfa 判负环,后跑 n 遍 dijkstra
模版
| C++ |
|---|
| #include <bits/stdc++.h>
using namespace std;
// 2023 OneWan
struct Node {
int to, val;
Node() = default;
Node(int to, int val) : to(to), val(val) {}
bool operator<(const auto &x) const {
return val > x.val;
}
};
int h[3005];
int dist[3005];
int cnt[3005];
bool vis[3005];
vector<Node> adj[3005];
int n;
bool spfa() {
for (int i = 1 ; i <= n ; i++) {
h[i] = 0x7fffffff;
vis[i] = false;
cnt[i] = 0;
adj[0].emplace_back(i, 0);
}
queue<int> que;
que.emplace(0);
h[0] = 0;
vis[0] = true;
while (!que.empty()) {
int p = que.front();
que.pop();
vis[p] = false;
for (auto &[to, val] : adj[p]) {
if (h[p] + val < h[to]) {
h[to] = h[p] + val;
if (vis[to] == false) {
vis[to] = true;
if (++cnt[to] >= n) {
return true;
}
que.emplace(to);
}
}
}
}
return false;
}
void dijkstra(int s) {
for (int i = 1 ; i <= n ; i++) {
dist[i] = 0x7fffffff;
vis[i] = false;
}
dist[s] = 0;
priority_queue<Node> que;
que.emplace(s, 0);
while (!que.empty()) {
auto x = que.top().to;
que.pop();
if (vis[x] == true) {
continue;
}
vis[x] = true;
for (auto &[to, val] : adj[x]) {
if (dist[x] + val < dist[to]) {
dist[to] = dist[x] + val;
que.emplace(to, dist[to]);
}
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int m;
cin >> n >> m;
for (int i = 0 ; i < m ; i++) {
int u, v, val;
cin >> u >> v >> val;
adj[u].emplace_back(v, val);
}
if (spfa()) {
cout << -1 << "\n";
return 0;
}
for (int i = 1 ; i <= n ; i++) {
for (auto &[to, val] : adj[i]) {
val += h[i] - h[to];
}
}
for (int i = 1 ; i <= n ; i++) {
dijkstra(i);
long long ans = 0;
for (int j = 1 ; j <= n ; j++) {
if (dist[j] == 0x7fffffff) {
ans += j * 1000000000L;
} else {
ans += 1LL * j * (dist[j] + h[j] - h[i]);
}
}
cout << ans << "\n";
}
return 0;
}
|
例题