Cod sursa(job #2565006)

Utilizator Dragos1226Dragos Chileban Dragos1226 Data 2 martie 2020 11:36:19
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.13 kb
#include<fstream>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<climits>

using namespace std;

ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int NMax = 2000, KMax = 17, oo = 1e9;
const long long OO = 1e15;
vector <int> G[NMax+5];
priority_queue <pair<int,int>> Q;
int N, M, K, Ck[KMax+5], D[NMax+5], Use[NMax+5], C[NMax+5][NMax+5];
long long DP[KMax+5][KMax+5];

void Read() {
    in >> N >> M >> K;
    for (int i = 1; i <= K; i++)
        in >> Ck[i];
    Ck[K+1] = 1;
    Ck[K+2] = N;
    for (int i = 0,x,y,c; i < M; i++) {
        in >> x >> y >> c;
        C[x][y] = C[y][x] = c;
        G[x].push_back(y);
        G[y].push_back(x);
    }
}

int find_min() {
    while(Use[Q.top().second])
        Q.pop();
    int res = Q.top().second;
    Q.pop();
    return res;
}

void Dijkstra (int Node) {
    for (int i = 1; i <= N; i++)
        D[i] = oo;

    memset(Use,0,sizeof Use);
    D[Node] = 0;

    Q.push(make_pair(D[Node], Node));

    for(int i = 1; i <= N && !Q.empty(); i++) {
        int Nod = find_min();
        Use[Nod] = 1;

        for (auto Vecin : G[Nod]) {
            int Cost = C[Nod][Vecin];

            if(D[Vecin] > D[Nod]+Cost) {
                D[Vecin] = D[Nod] + Cost;
                Q.push(make_pair(-D[Vecin], Vecin));
            }
        }
    }
    for (int i = 1; i <= K+2; i++)
        if (Ck[i] != Node)
            C[Node][Ck[i]] = D[Ck[i]];
}

void Solve() {
    for (int i = 1; i <= K+2; i++)
        Dijkstra(Ck[i]);

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

    for (int Conf = 1; Conf < (1<<(K+2)); Conf++)
        for (int i = 0; i < K+2; i++) {
            if (Conf & (1<<i))
                for (int j = 0; j < K + 2; j++) {
                    if (Conf & (1<<j))
                        DP[Conf][i] = min(DP[Conf][i], DP[Conf^(1<<i)][j] + C[Ck[i+1]][Ck[j+1]]);
                }
        }

    int Sol = DP[(1<<(K+2))-1][K + 1];
    out << Sol << '\n';
}

int main() {
    Read();
    Solve();
}