Cod sursa(job #2550747)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 19 februarie 2020 09:19:31
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2 kb
#include <bits/stdc++.h>

using namespace std;

const int N = 10009, K = 15;

int dep[K + 2][K + 2];
int drum[(1<<K) + 7][K + 2];
int dist[N], c[K + 2];
vector < pair < int, int > > adia[N];
int n;

void Dij(int start) {
    fill(dist, dist + n + 2, 1e9 + 7);
    set < pair < int, int > > s;///<dist, nod>
    dist[start] = 0;
    s.insert({dist[start], start});
    while (s.size()) {
        auto x = *s.begin();
        s.erase(x);
        if (dist[x.second] != x.first)
            continue;
        for (auto i : adia[x.second]) {
            if (dist[i.first] > x.first + i.second) {
                dist[i.first] = x.first + i.second;
                s.insert({dist[i.first], i.first});
            }
        }
    }
}

int main()
{
    ifstream fin("ubuntzei.in");
    ofstream fout("ubuntzei.out");
    ios_base::sync_with_stdio(NULL);
    cin.tie(0);
    cout.tie(0);
    int k, m, x, y, z;
    fin >> n >> m;
    fin >> k;
    for (int i = 0; i < k; ++i)
        fin >> c[i];
    while (m--) {
        fin >> x >> y >> z;
        adia[x].push_back({y, z});
        adia[y].push_back({x, z});
    }
    c[k] = 1;
    c[k + 1] = n;
    Dij(1);
    if (k == 0)
        return cout << dist[n] << '\n', 0;
    for (int i = 0; i < k; ++i)
        drum[1<<i][i] = dist[c[i]];
    for (int i = 0; i < k; ++i) {
        Dij(c[i]);
        for (int j = 0; j < k; ++j)
            dep[i][j] = dist[c[j]];
    }
    for (int msk = 1; msk < (1<<k) - 1; ++msk) {
        for (int bit = 0; bit < k; ++bit) {
            if (!(msk&(1<<bit)))
                continue;
            for (int urm = 0; urm < k; ++urm) {
                if (msk&(1<<urm))
                    continue;
                drum[msk^(1<<urm)][urm] = min(drum[msk^(1<<urm)][urm], drum[msk][bit] + dep[bit][urm]);
            }
        }
    }
    Dij(n);
    int ans(1e9 + 7);
    for (int i = 0; i < k; ++i)
        ans = min(ans, drum[(1<<k) - 1][i] + dist[c[i]]);
    fout << ans;
    return 0;
}