Cod sursa(job #3242417)

Utilizator AlexPlesescuAlexPlesescu AlexPlesescu Data 11 septembrie 2024 23:20:17
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <bits/stdc++.h>

using namespace std;
#define MASK (1 << 16)
#define KMAX 20
#define pb push_back
const int INF = 1e8, NMAX = 2e3 + 7;

struct Edges {
    int nod;
    int cost;
};

struct cmp {
    bool operator() (const Edges& a, const Edges& b) const {
        return a.cost > b.cost;
    }
};

int dp[KMAX][MASK], c[KMAX], cmin[NMAX][NMAX], cc[KMAX], n, m, k, minim = INF, nod_final;

vector<Edges> G[NMAX];

void dijkstra(int start) {
    priority_queue<Edges, vector<Edges>, cmp> Q;
    Q.push({ start, 0 });
    cmin[start][start] = 0;
    while (!Q.empty()) {
        int node = Q.top().nod;
        int dist = Q.top().cost;
        Q.pop();
        for (auto& vec : G[node]) {
            if (dist + vec.cost < cmin[start][vec.nod]) {
                cmin[start][vec.nod] = dist + vec.cost;
                Q.push({ vec.nod, cmin[start][vec.nod] });
            }
        }
    }
}

int main() {
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    cin >> n >> m >> k;
    for (int i = 0; i < k; i++)
        for (int mask = 0; mask < (1 << k); mask++)
            dp[i][mask] = INF;
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            cmin[i][j] = INF;
    for (int i = 0; i < k; i++)
        cin >> c[i];
    for (int i = 0; i < m; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        G[x].pb({ y, z });
        G[y].pb({ x, z });
    }
    dijkstra(1);
    dijkstra(n);
    for (int i = 0; i < k; i++)
        dijkstra(c[i]);
    if (k == 0) {
        cout << cmin[1][n];
        return 0;
    }
    for (int i = 0; i < k; i++) {
        dp[i][(1 << i)] = cmin[1][c[i]];
    }
    for (int mask = 1; mask < (1 << k); mask++) {
        for (int i = 0; i < k; i++) {
            if (mask & (1 << i)) {
                for (int j = 0; j < k; j++) {
                    if (i != j && (mask & (1 << j))) {
                        dp[i][mask] = min(dp[i][mask], dp[j][mask ^ (1 << i)] + cmin[c[j]][c[i]]);
                    }
                }
            }
        }
    }
    int ans = INF;
    for (int i = 0; i < k; i++) {
        ans = min(ans, dp[i][(1 << k) - 1] + cmin[c[i]][n]);
    }
    cout << ans;
}