涉及知识点:动态规划。
解题思路
设 \(dp_i\) 为得到 \(i\) 最小的花费。
可以得到转移方程:\(dp_{a_i} = \min(dp_{x_i} + dp_{y_i}, dp_{a_i})\)。
很明显最多迭代 \(n\) 次,还需要再外面套一个循化即可。
但是有些 OJ
没有洛谷跑得快,所以需要加一点优化。
如果当前循环没有更新任何一个数,说明当前每个数都是最优的,直接退出循环。
代码
#include <bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define fre(x) freopen(x".in", "r", stdin); freopen(x".out", "w", stdout);const int N = 100010;int n, m;
int a[N], x[N], y[N], z[N];
int dp[N];signed main() {IOS;cin >> n >> m;for (int i = 1; i <= n; i ++ ) cin >> a[i];for (int i = 1; i <= m; i ++ ) {int a, b, c;cin >> a >> b >> c;x[i] = a;y[i] = b;z[i] = c;}for (int i = 1; i <= n; i ++ ) dp[i] = a[i];for (int i = 1; i < n; i ++ ) {bool flag = false;for (int j = 1; j <= m; j ++ ) {if (dp[y[j]] + dp[z[j]] < dp[x[j]]) {dp[x[j]] = dp[y[j]] + dp[z[j]];flag = true;}}if (!flag) break;}cout << dp[1] << endl;return 0;
}