今天大家会感受到 Bellman_ford 算法系列在不同场景下的应用。
建议依然是:一刷的时候,能理解 原理,知道Bellman_ford 解决不同场景的问题 ,照着代码随想录能抄下来代码就好,就算达标。
二刷的时候自己尝试独立去写,三刷的时候 才能有一定深度理解各个最短路算法。
Bellman_ford 队列优化算法(又名SPFA)
#include <iostream>
#include <list>
#include <queue>
#include <vector>
#include <climits>
using namespace std;
struct Edge {
int to;
int val;
Edge(int to,int val):to(to),val(val){}
};
void solve() {
int n, m, v1, v2, val;
cin >> n >> m;
vector<list<Edge>>grid(n + 1);
for (int i = 0; i < m; i++) {
cin >> v1 >> v2 >> val;
grid[v1].push_back({ v2,val });
}
int start = 1;
int end = n;
vector<int>minDist(n + 1, INT_MAX);
vector<bool>isInQueue(n + 1);
queue<int>que;
minDist[start] = 0;
que.push(start);
while (!que.empty()) {
int node = que.front();
que.pop();
isInQueue[node] = false;
for (Edge edge : grid[node]) {
int to = edge.to;
int from = node;
int value = edge.val;
if (minDist[to] > minDist[from] + value) {
minDist[to] = minDist[from] + value;
if (isInQueue[to]==false) {
que.push(to);
isInQueue[to] =true;
}
}
}
}
if (minDist[end] == INT_MAX)cout << "unconnected" << endl;
else cout << minDist[end] << endl;
}
int main() {
solve();
return 0;
}
bellman_ford之判断负权回路
#include <iostream>
#include <vector>
#include <list>
#include <climits>
#include <queue>
using namespace std;
void solve() {
int n, m, v1, v2, val;
cin >> n >> m;
vector<vector<int>>grid;
for (int i = 0; i < m; i++) {
cin >> v1 >> v2 >> val;
grid.push_back({v1, v2,val });
}
int start = 1;
int end = n;
bool flag = false;
vector<int>minDist(n + 1,INT_MAX);
minDist[start] = 0;
for (int i = 1; i <= n; i++) {
for (vector<int>& side : grid) {
int from = side[0];
int to = side[1];
int price = side[2];
if (i < n) {
if (minDist[from] != INT_MAX && minDist[to] > minDist[from] + side[2])minDist[to] = minDist[from] + side[2];
}
else {
if (minDist[from] != INT_MAX && minDist[to] > minDist[from] + side[2])flag = true;
}
}
}
if (flag)cout << "circle" << endl;
else if (minDist[end] == INT_MAX) {
cout << "unconnected" << endl;
}
else {
cout << minDist[end] << endl;
}
}
int main() {
solve();
return 0;
}
使用队列
#include <iostream>
#include <vector>
#include <list>
#include <queue>
#include <climits>
using namespace std;
struct Edge {
int to, val;
Edge(int to,int val):to(to),val(val){}
};
void solve() {
int n, m, v1, v2, val;
cin >> n >> m;
vector<list<Edge>>grid(n + 1);
for (int i = 0; i < m; i++) {
cin >> v1 >> v2 >> val;
grid[v1].push_back(Edge(v2, val));
}
int start = 1;
int end = n;
vector<int>minDist(n + 1,INT_MAX);
minDist[start] = 0;
queue<int>que;
que.push(start);
vector<int>count(n + 1, 0);
count[start]++;
bool flag = false;
while (!que.empty()){
int node = que.front();
que.pop();
for (Edge edge : grid[node]) {
int from = node;
int to = edge.to;
int value = edge.val;
if (minDist[to] > minDist[from] + value) {
minDist[to] = minDist[from] + value;
que.push(to);
count[to]++;
if (count[to] == n) {
flag = true;
while (!que.empty())que.pop();
break;
}
}
}
}
if (flag)cout << "circle" << endl;
else if (minDist[end] == INT_MAX) {
cout << "unconnected" << endl;
}
else {
cout << minDist[end] <<endl;
}
}
int main() {
solve();
return 0;
}
bellman_ford之单源有限最短路
#include <iostream>
#include <queue>
#include <list>
#include <vector>
#include <climits>
using namespace std;
void solve() {
int start,end,k,n, m, v1, v2, val;
cin >> n >> m;
vector<vector<int>>grid;
for (int i = 0; i < m; i++) {
cin >> v1 >> v2 >> val;
grid.push_back({ v1,v2,val });
}
cin >> start >> end >> k;
vector<int>minDist(n + 1, INT_MAX);
minDist[start] = 0;
vector<int>minDist_copy(n + 1);
for (int i = 1; i <= k + 1; i++) {
minDist_copy = minDist;
for (vector<int>& side : grid) {
int from = side[0];
int to = side[1];
int price = side[2];
if (minDist_copy[from] != INT_MAX && minDist[to] > minDist_copy[from] + price) {
minDist[to] = minDist_copy[from] + price;
}
}
}
if (minDist[end] == INT_MAX)cout << "unreachable" << endl;
else cout << minDist[end] << endl;
}
int main() {
solve();
return 0;
}
总结
这个题看的有点不是太懂,二刷继续。