正确答案应该是多少
把 0 到 3 的所有路径都枚举一遍,取最短的。运行下面这段程序:
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const ll INF = 1000000000; // 走不到的点记这个值,输出时写成 -1
using Graph = vector<vector<pair<int, int>>>; // g[u] 里放 (邻居 v, 边权 w)
// 七个点的无向图(和 Python 版同一组数据):0-1:2 0-2:1 1-3:3 2-4:9 3-4:1 5-6:7
const vector<vector<int>> E7 = {{0, 1, 2}, {0, 2, 1}, {1, 3, 3}, {2, 4, 9}, {3, 4, 1}, {5, 6, 7}};
// 主连通块五个点、五条边(求最小生成树用)
const vector<vector<int>> E5 = {{0, 1, 2}, {0, 2, 1}, {1, 3, 3}, {2, 4, 9}, {3, 4, 1}};
// 有向负权反例:0→1:4 0→2:5 2→1:-3 1→3:1
const Graph NEG = {{{1, 4}, {2, 5}}, {{3, 1}}, {{1, -3}}, {}};
// 同一张图,只把 2→1 那条边改成 +3
const Graph POS = {{{1, 4}, {2, 5}}, {{3, 1}}, {{1, 3}}, {}};
// 有负环:0→1:1 1→2:-1 2→1:-1
const Graph CYC = {{{1, 1}}, {{2, -1}}, {{1, -1}}};
ll best_path;
void go(const Graph& g, int u, int t, ll c, vector<bool>& seen) {
if (u == t) {
best_path = min(best_path, c);
return;
}
for (auto [v, w] : g[u]) {
if (seen[v]) continue;
seen[v] = true;
go(g, v, t, c + w, seen);
seen[v] = false;
}
}
ll brute(const Graph& g, int s, int t) {
// 把 s 到 t 所有不重复经过点的路径都走一遍,取最短
best_path = INF;
vector<bool> seen(g.size(), false);
seen[s] = true;
go(g, s, t, 0, seen);
return best_path;
}
int main() {
cout << brute(NEG, 0, 3) << endl;
}
(本题用 g++ -std=c++17 -O0 编译。)
全部评论