Cod sursa(job #3231273)

Utilizator catalinmarincatalinmarin catalinmarin Data 25 mai 2024 15:30:16
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

struct stare{
    int curr;
    int total;
    bool operator < (const stare other) const{
        return total > other.total;
    }
};

struct vecin{
    int next;
    int cost;
};

int n, m, k;

vector<int> loc_ubu;
vector<vecin> v[2005];

int dp[65536][17];
int dist[17][2005];
bool visited[2005];

priority_queue<stare> pq;

void dijkstra(int ubu){
    while (!pq.empty()){
        stare frn = pq.top();
        pq.pop();
        if (visited[frn.curr])
            continue;
        visited[frn.curr] = true;
        for (int i = 0; i < v[frn.curr].size(); i++){
            stare vecin = {v[frn.curr][i].next, frn.total + v[frn.curr][i].cost};
            if (vecin.total < dist[ubu][vecin.curr]){
                dist[ubu][vecin.curr] = vecin.total;
                pq.push(vecin);
            }
        }
    }
}

int main(){
    fin >> n >> m >> k;
    loc_ubu.resize(k + 1);
    loc_ubu[0] = 1;
    for (int i = 1; i <= k; i++){
        fin >> loc_ubu[i];
    }
    for (int i = 0; i <= k; i++){
        for (int j = 1; j <= n; j++)
            dist[i][j] = 1e9;
    }

    for (int i = 1; i <= m; i++){
        int a, b, c;
        fin >> a >> b >> c;
        v[a].push_back({b, c});
        v[b].push_back({a, c});
    }

    for (int i = 0; i <= k; i++){
        for (int j = 1; j <= n; j++)
            visited[j] = false;
        dist[i][loc_ubu[i]] = 0;
        stare init = {loc_ubu[i], 0};
        pq.push(init);
        dijkstra(i);
    }

    if (k == 0) {
        fout << dist[0][n];
        return 0;
    }

    for (int i = 1; i <= (1 << k); i++){
        for (int j = 0; j < 16;  j++)
            dp[i][j] = 1e9;
    }

    for (int i = 0; i < k; i++){
        dp[(1 << i)][i] = dist[0][loc_ubu[i + 1]];
    }

    for (int mask = 1; mask < (1 << k); mask++){
        for (int u = 0; u < k; u++){
            if (dp[mask][u] != 1e9) {
                continue;
            }
            int bit_u = (1 << u);
            if (mask & bit_u) {
                int old_mask = mask - bit_u;
                for (int j = 0; j < k; j++) {
                    int bit_j = (1 << j);
                    if (old_mask & bit_j) {
                        dp[mask][u] = min(dp[old_mask][j] + dist[j + 1][loc_ubu[u + 1]], dp[mask][u]);
                    }
                }
            }
        }
    }

    int ans = 2e9;
    int mask_full = (1 << k) - 1;

    for (int i = 1; i <= k; i++){
        ans = min(ans, dp[mask_full][i - 1] + dist[i][n]);
    }
    fout << ans;
    return 0;
}