Cod sursa(job #2362848)

Utilizator Dragos123Tatar Dragos Vlad Dragos123 Data 3 martie 2019 12:04:33
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

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

const int Inf = (1 << 30);

struct State{
    int node, cost;

    bool operator< (const State& st) const
    {
        return cost > st.cost;
    }
};

using VI = std::vector<int>;
using VVI = std::vector<VI>;
using VVP = std::vector<std::vector<std::pair<int, int>>>;

int n, m, k;
int res;

VI t, s;
VVI d, dist;
VVP G;

void ReadData();
void Dijkstra(int x);
void Solve();
void Write();

int main ()
{
    ReadData();
    Solve();
    Write();

    fin.close();
    fout.close();

    return 0;
}

void ReadData()
{
    fin >> n >> m >> k;
    G = VVP(n + 1);
    s = VI(k + 1);
    t = VI(n + 1, Inf);

    for (int i = 0; i < k; ++i)
        fin >> s[i];

    int x, y, cost;

    for (int i = 1; i <= m; ++i)
    {
        fin >> x >> y >> cost;
        G[x].push_back({y, cost});
        G[y].push_back({x, cost});
    }
}

void Dijkstra(int x)
{
    std::priority_queue<State> Q;

    for (int i = 1; i <= n; ++i)
        t[i] = Inf;

    Q.push({x, 0});
    t[x] = 0;

    while (!Q.empty())
    {
        int node = Q.top().node;
        int cost = Q.top().cost;

        Q.pop();

        for(const auto& y : G[node])
        {
            int next_node = y.first;
            int cc = y.second;

            if (t[next_node] > t[node] + cc)
            {
                t[next_node] = t[node] + cc;
                Q.push({next_node, cc});
            }
        }
    }
}

void Solve()
{
    dist = VVI(n + 1);
    for (int i = 1; i <= n; ++i)
    {
        Dijkstra(i);
        dist[i].push_back(0);
        for (int j = 1; j <= n; ++j)
            dist[i].push_back(t[j]);
    }
    Dijkstra(1);

    d = VVI(1 << k, VI(k, Inf));

    for (int i = 0; i < k; ++i)
        d[1 << i][i] = t[s[i]];

    for (int i = 1; i < (1 << k); ++i)
        for (int j = 0; j < k; ++j)
            if (i & (1 << j))
                for (int p = 0; p < k; ++p)
                    if (!(i & (1 << p)))
                        d[i | (1 << p)][p] = std::min(d[i | (1 << p)][p], d[i][j] + dist[j + 1][s[p]]);

    res = Inf;
    for (int i = 0; i < k; ++i)
        res = std::min(res, d[(1 << k) - 1][i] + dist[i + 1][n]);
}

void Write()
{
    fout << res;
}