Cod sursa(job #2386617)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 23 martie 2019 12:00:42
Problema Ubuntzei Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <utility>
#include <queue>

#define pp pair<int, int>

using namespace std;

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

const int ConfMax = (1 << 15), KMax = 15, NMax = 2000, oo = 2e9;

int N, M, K, DP[ConfMax + 5][KMax + 5], C[KMax + 5][KMax + 5], D[NMax + 5];

bool Use[NMax + 5];

///Cij - distanta minima de la nodul V[i] la nodul V[j]

vector < pair<int, int> > G[NMax + 5];
vector <int> V;

priority_queue<pp, vector<pp>, greater<pp> > Q;

void Dijkstra(int k)
{
    int Nod = V[k], Vecin, Cost;

    for(int i = 1; i <= N; i++)
        D[i] = oo, Use[i] = 0;

   D[Nod] = 0; Q.push({D[Nod], Nod});

    while(!Q.empty())
    {
        Nod = Q.top().second; Q.pop();

        if(Use[Nod]) continue;

        Use[Nod] = true;

        for(auto x : G[Nod])
        {
            Vecin = x.first, Cost = x.second;

            if(D[Nod] + Cost < D[Vecin])
            {
                D[Vecin] = D[Nod] + Cost;
                Q.push({D[Vecin], Vecin});
            }
        }
    }
    for(int i = 0; i < K; i++)
        C[k][i] = D[V[i]];
}

void Read()
{
    fin >> N >> M >> K;

    V.push_back(1), V.push_back(N);

    for(int i = 1, x; i <= K; i++)
        fin >> x, V.push_back(x);

    K += 2;

    for(int i = 0, x, y, c; i < M; i++)
    {
        fin >> x >> y >> c;

        G[x].push_back({y, c});
        G[y].push_back({x, c});
    }
}

void Solve_and_Print()
{
    int Lim = (1 << K) - 1;

    for(int i = 1; i <= Lim; i++)
        for(int j = 0; j <= K; j++)
            DP[i][j] = oo;

    DP[1][0] = 0;

    for(int i = 1; i <= Lim; i++)
        for(int j = 0; j < K; j++)
            if(i & (1 << j))
            {
                for(int k = 0; k < K; k++)
                {
                    DP[i][j] = min(DP[i][j], DP[i - (1 << j)][k] + C[k][j]);
                }
            }
    fout << DP[Lim][1] << '\n';
}

int main()
{
    Read();

    for(int i = 0; i < K; i++) Dijkstra(i);

    Solve_and_Print();

    return 0;
}