Cod sursa(job #2568007)

Utilizator MarianConstantinMarian Constantin MarianConstantin Data 3 martie 2020 20:10:00
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <bits/stdc++.h>
#define pb push_back

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
const int MAXN = 2005, MAXK = 16, INF = 0x3f3f3f3f, MAX = 1 << MAXK;

set<pair<int, int>> heap;
vector<pair<int, int>> graph[MAXN];
bitset<MAX> inQ[MAXN];
int dp[MAXK][MAX], dist[MAXN][MAXN], fr[MAXK], pos[MAXN], n, m, k, last;
queue<pair<int, int>> q;

void init()
{
    for (int i = 1; i <= n; ++i)
        pos[i] = -1;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            dist[i][j] = INF;
    last = (1 << k) - 1;
    for (int i = 0; i <= k; ++i)
        for (int j = 0; j <= last; ++j)
            dp[i][j] = INF;
}

void read()
{
    fin >> n >> m >> k;
    init();
    for (int i = 0; i < k; ++i) {
        int x;
        fin >> x;
        pos[x] = i;
        fr[i] = x;
    }
    for (int i = 0; i < m; ++i) {
        int x, y, c;
        fin >> x >> y >> c;
        graph[x].pb({y, c});
        graph[y].pb({x, c});
    }
}

void dijkstra(int start)
{
    dist[start][start] = 0;
    heap.insert({0, start});
    while (!heap.empty()) {
        int node = heap.begin()->second;
        heap.erase(heap.begin());
        for (const auto& it: graph[node])
            if (dist[start][node] + it.second < dist[start][it.first]) {
                if (dist[start][it.first] != INF)
                    heap.erase({dist[start][it.first], it.first});
                dist[start][it.first] = dist[start][node] + it.second;
                heap.insert({dist[start][it.first], it.first});
            }
    }
}

void solve()
{
    for (int i = 0; i < k; ++i)
        dp[i][1 << i] = dist[1][fr[i]];
    for (int i = 0; i < k; ++i)
        for (int j = 0; j <= last; ++j)
            if (j & (1 << i)) {
                for (int p = 0; p < k; ++p)
                    if (j & (1 << p))
                        dp[i][j] = min(dp[i][j], dp[p][j ^ (1 << i)] + dist[fr[p]][fr[i]]);
            }
    for (int i = 0; i < k; ++i)
        dp[k][last] = min(dp[k][last], dp[i][last] + dist[fr[i]][n]);
}

int main()
{
    read();
    dijkstra(1);
    for (int i = 0; i < k; ++i)
        dijkstra(fr[i]);
    solve();
    fout << dp[k][last];
    return 0;
}