P10110 [GESP202312 七级] 商品交易

· · 题解

容易发现,如果经过了 k 次交易后从 a 得到 b,假设商品的交易过程是 a \to x_1 \to x_2 \to \dots \to x_{k - 1} \to b,那么收益就是 (v_{x_1} - v_a + 1) + (v_{x_2} + v_{x_1} + 1) + \dots + (v_b - v_{k - 1} + 1)。把 +1 都提出来,共有 k 个。余下的项去括号,可以看到 v_{x_i} 的符号以正负各出现了一次,被抵消掉了。所以总收益就是 v_b - v_a + k

对于一个交换 $x_i$ 和 $y_i$ 商品的商人,连边 $y_i \to x_i$,表示从 $y_i$ 得到 $x_i$ 需要一次交易。那么从 $a$ 到 $b$ 的最短路就是最小交换次数。 边权全为 $1$,跑 bfs 即可。 ```cpp #include <bits/stdc++.h> int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int n, m, a, b; std::cin >> n >> m >> a >> b; std::vector<int> v(n); for (auto &i : v) std::cin >> i; std::vector<std::vector<int>> chg(n); for (int x, y; m; --m) { std::cin >> x >> y; chg[x].push_back(y); } std::vector<int> f(n, 1100000000); f[a] = 0; std::queue<int> Q; for (Q.push(a); !Q.empty(); Q.pop()) { int u = Q.front(); for (auto v : chg[u]) { if (f[v] > f[u] + 1) { f[v] = f[u] + 1; Q.push(v); } } } if (f[b] == 1100000000) { std::cout << "No solution\n"; } else { std::cout << f[b] + v[b] - v[a] << std::endl; } } ```