Cod sursa(job #3356197)

Utilizator MihneaStoicaMihnea Teodor Stoica MihneaStoica Data 30 mai 2026 10:42:59
Problema Team Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 5.72 kb
#pragma GCC optimize("Ofast,unroll-loops")
#include <bits/stdc++.h>
using namespace std;

using uint = unsigned int;
using ll   = long long;
using ull  = unsigned long long;
using ld   = long double;

#if 0
#define int  ll
#define uint ull
#endif

/**
 *!Problem: Team
 * URL: https://infoarena.ro/problema/team
 * TL: 100 ms
 * ML: 20 MB
 *
 * Good Luck!
*/

struct state {
    int i, j, u, t;

    const bool operator<(const state &b) const { return this->t > b.t; }
};

inline void init() {
    int p, n, m;
    cin >> p >> n >> m;

    vector<vector<pair<int, int>>> adj(n + 1);
    for (int _ = 1; _ <= m; _++) {
        int i, j, c;
        cin >> i >> j >> c;

        adj[i].push_back({j, c});
        adj[j].push_back({i, c});
    }

    vector<int> dropoff(p + 1);
    for (int i = 1; i <= p; i++) { cin >> dropoff[i]; }

    vector<int> c_drop(p + 1);
    vector<vector<int>> adj2(p + 1, vector<int>(p + 1));
    for (int i = 1; i <= p; i++) {
        priority_queue<pair<int, int>> pq;
        pq.push({0, dropoff[i]});
        vector<int> dp(n + 1, INT32_MAX);
        dp[dropoff[i]] = 0;

        while (!pq.empty()) {
            auto [y, u] = pq.top();
            pq.pop();
            y = -y;

            if (dp[u] < y) continue;

            for (auto [v, c] : adj[u]) {
                if (dp[v] > c + dp[u]) {
                    dp[v] = c + dp[u];
                    pq.push({-dp[v], v});
                }
            }
        }

        // adj2[i] = dp;

        for (int j = 1; j <= p; j++) { adj2[i][j] = dp[dropoff[j]]; }
        c_drop[i] = dp[1];
    }

    vector<vector<vector<int>>> dp(
        p + 1, vector<vector<int>>(p + 1, vector<int>(p + 1, 1e9)));
    // dp[1][p][1] = 0;

    // priority_queue<state> q;
    // q.push({1, p, 1, 0});

    for (int i = 1; i <= p; i++) {
        // q.push({i, i, i, 0});
        dp[i][i][i] = 0;
    }

    for (int st = p; st >= 1; st--) {
        for (int dr = st; dr <= p; dr++) {
            priority_queue<pair<int, int>> pq;

            if (st < dr) {
                int m1 = dp[st + 1][dr][st];
                if (m1 < dp[st][dr][st]) { dp[st][dr][st] = m1; }

                int m2 = dp[st][dr - 1][dr];
                if (m2 < dp[st][dr][dr]) { dp[st][dr][dr] = m2; }
            }

            for (int mid = st + 1; mid < dr; mid++) {
                int merge_cost = dp[st][mid - 1][mid] + dp[mid + 1][dr][mid];

                // cout << "? st = " << st << " mid = " << mid
                //      << " dr = " << dr << " u = " << u
                //      << " merge_cost = " << merge_cost
                //      << " dp[st][dr][u] = " << dp[st][dr][u] << '\n';

                if (merge_cost < dp[st][dr][mid]) {
                    dp[st][dr][mid] = merge_cost;
                }
            }

            for (int i = st; i <= dr; i++) { pq.push({-dp[st][dr][i], i}); }

            while (!pq.empty()) {
                auto [y, u] = pq.top();
                pq.pop();
                y = -y;

                for (int v = 1; v <= p; v++) {
                    int c = adj2[u][v];
                    if (y + c < dp[st][dr][v]) {
                        dp[st][dr][v] = y + c;
                        pq.push({-dp[st][dr][v], v});
                    }
                }
            }
        }
    }

    // here lies my spaghetti code
    // while (!q.empty()) {
    //     auto [i, j, u, t] = q.top();
    //     // cout << i << " " << j << " " << u << " " << t << '\n';
    //     q.pop();

    //     if (dp[i][j][u] < t) continue;

    //     for (auto &[v, c] : adj[u]) {
    //         if (t + c < dp[i][j][v]) {
    //             dp[i][j][v] = t + c;
    //             q.push({i, j, v, t + c});
    //             // for (int k = i; k <= j; k++) {
    //             //     int l = k;
    //             //     while (l <= j && dropoff[l] != v) l++;
    //             //     l--;
    //             //     if (k <= l) {
    //             //         // dp[k][l][v] = 0;
    //             //         q.push({k, l, v, t + c});
    //             //         k = l;
    //             //     }
    //             // }
    //         }
    //     }

    //     for (int st = 1; st + 1 < p; st++) {
    //         for (int dr = st + 2; dr <= p; dr++) {
    // if (dropoff[st] == u) {
    //     int merge_cost = dp[st + 1][dr][u];
    //     if (merge_cost < dp[st][dr][u]) {
    //         dp[st][dr][u] = merge_cost;
    //         q.push({st, dr, u, dp[st][dr][u]});
    //     }
    // }
    // if (dropoff[dr] == u) {
    //     int merge_cost = dp[st][dr - 1][u];
    //     if (merge_cost < dp[st][dr][u]) {
    //         dp[st][dr][u] = merge_cost;
    //         q.push({st, dr, u, dp[st][dr][u]});
    //     }
    // }

    // for (int mid = st + 1; mid < dr; mid++) {
    //     if (dropoff[mid] == u) {
    //         int merge_cost =
    //             dp[st][mid - 1][u] + dp[mid + 1][dr][u];

    //         // cout << "? st = " << st << " mid = " << mid
    //         //      << " dr = " << dr << " u = " << u
    //         //      << " merge_cost = " << merge_cost
    //         //      << " dp[st][dr][u] = " << dp[st][dr][u] << '\n';

    //         if (merge_cost < dp[st][dr][u]) {
    //             dp[st][dr][u] = merge_cost;
    //             q.push({st, dr, u, dp[st][dr][u]});
    //         }
    //     }
    // }
    //         }
    //     }
    // }

    int minn = INT32_MAX;
    for (int i = 1; i <= p; i++) { minn = min(minn, c_drop[i] + dp[1][p][i]); }
    cout << minn << '\n';
}
inline void tc() {}

#define FIO  0
#define FILE "team"

signed main() {
#if FIO
    freopen(FILE ".in", "r", stdin);
    freopen(FILE ".out", "w", stdout);
#endif
    // ios_base::sync_with_stdio(false);
    // cin.tie(nullptr);
    init();
    int tt;
    if (!(cin >> tt)) return 0;
    while (tt--) tc();
    return 0;
}