涉及知識點:動態規劃。
解題思路
設 \(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;
}