Cod sursa(job #3173146)

Utilizator octavian202Caracioni Octavian Luca octavian202 Data 21 noiembrie 2023 22:03:06
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

#define pii pair<int, int>

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int NMAX = 2005;
vector<pii> g[NMAX];
vector<int> conf_de_biti[16];

void dijkstra(int s, vector<int> &dist) {
    priority_queue<pii, vector<pii>, greater<pii> > pq;
    pq.push(make_pair(0, s));
    dist[s] = 0;

    while (!pq.empty()) {
        int curr = pq.top().second, cv = pq.top().first;
        pq.pop();

        if (dist[curr] < cv)
            continue;

        for (auto muchie : g[curr]) {
            int cost = muchie.first, nod = muchie.second;
            if (dist[curr] + cost < dist[nod]) {
                dist[nod] = dist[curr] + cost;
                pq.push(make_pair(dist[nod], nod));
            }
        }
    }
}

int main() {

    int n, m, k;
    fin >> n >> m >> k;
    vector<vector<int> > d(k + 1, vector<int>(n + 1, 1e9));
    vector<vector<int> > dp(k + 1, vector<int>((1<<k) + 1, 1e9));
    vector<int> ub(k + 1);

    for (int i = 1; i <= k; i++) {
        fin >> ub[i];
    }

    for (int i = 1; i <= m; i++) {
        int x, y, c;
        fin >> x >> y >> c;

        g[x].push_back(make_pair(c, y));
        g[y].push_back(make_pair(c, x));
    }

    dijkstra(1, d[0]);
    for (int i = 1; i <= k; i++) {
        dijkstra(ub[i], d[i]);
        dp[i][(1 << (i - 1))] = d[0][ub[i]];
    }

    for (int conf = 1; conf < (1 << k); conf++) {
        conf_de_biti[__builtin_popcount(conf)].push_back(conf);
    }

    for (int nr_biti = 1; nr_biti < k; nr_biti++) {
        for (auto conf : conf_de_biti[nr_biti]) {
            for (int p = 0; p < k; p++) {
                if (((1 << p) & conf) != 0)
                    continue;

                int pos = p + 1;
                int nxt = ((1 << p) | conf);

                for (int curr = 1; curr <= k; curr++) {
                    if ((conf & (1 << (curr - 1))) == 0)
                        continue;

                    dp[pos][nxt] = min(dp[pos][nxt], dp[curr][conf] + d[curr][ub[pos]]);
                }
            }
        }
    }

    int conf_total = (1 << k) - 1;
    int res = 1e9;
    for (int i = 1; i <= k; i++) {
        res = min(res, dp[i][conf_total] + d[i][n]);
    }

    fout << res;


    return 0;
}