Cod sursa(job #2850980)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 17 februarie 2022 20:54:14
Problema Ubuntzei Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

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

typedef pair<int, int> pii;

const int INF = 2e9;
const int N = 2e3;
const int K = 15;
const int MASK = (1 << K);

int n, m, k;
int d[K + 5][K + 5], dist[N + 5], dp[K + 5][MASK + 5];
vector<int> v;
vector<pii> adj[N + 5];

void dijkstra(int index, int start) {
    priority_queue<pii> pq;
    vector<int> dist(N + 5, INF);
    bitset<N + 5> vis;
    dist[start] = 0;
    pq.push({0, start});
    while (!pq.empty()) {
        pii buffer = pq.top();
        pq.pop();
        int node = buffer.second, cost = abs(buffer.first);
        if (vis[node])
            continue;
        vis[node] = true;
        for (auto it: adj[node]) {
            if (dist[it.first] > cost + it.second) {
                dist[it.first] = cost + it.second;
                pq.push({-dist[it.first], it.first});
            }
        }
    }

    for (int i = 0; i < k; i++) {
        d[index][i] = min(d[index][i], dist[v[i]]);
        d[i][index] = min(d[i][index], dist[v[i]]);
    }
}

int main() {
    in >> n >> m >> k;
    v.push_back(1);
    for (int i = 1; i <= k; i++) {
        int x;
        in >> x;
        v.push_back(x);
    }
    v.push_back(n);
    k = v.size();
    for (int i = 1; i <= m; i++) {
        int x, y, c;
        in >> x >> y >> c;
        adj[x].emplace_back(y, c);
        adj[y].emplace_back(x, c);
    }

    for (int i = 0; i < k; i++)
        for (int j = 0; j < k; j++)
            d[i][j] = INF;
    for (int i = 0; i < k; i++)
        dijkstra(i, v[i]);

    for (int i = 0; i < k; i++)
        for (int j = 0; j < (1 << k); j++)
            dp[i][j] = INF;
    dp[0][1] = 0;
    for (int j = 0; j < (1 << k); j++) {
        for (int i = 0; i < k; i++) {
            if (j & (1 << i)) {
                int mask = j ^ (1 << i);
                for (int u = 0; u < k; u++)
                    if (mask & (1 << u))
                        dp[i][j] = min(dp[i][j], dp[u][mask] + d[u][i]);
            }
        }
    }
    out << dp[k - 1][(1 << k) - 1] << '\n';

    return 0;
}