題解:P7082 [NWRRC2013] Dwarf Tower

zla_2012發表於2024-11-06

涉及知識點:動態規劃。

解題思路

\(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;
}