Cod sursa(job #2321292)

Utilizator SqueekDanielTodasca Daniel SqueekDaniel Data 15 ianuarie 2019 22:02:15
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <bits/stdc++.h>

int bitscount(int x) {
    if (x == 0) return 0;
    return x&1 + bitscount(x/2);
}

#define int_pair std::pair <int, int>
#define MAXBITS 131075
#define MAXN 2005
#define MAXK 18
#define inf  2000000005

int N, M, K, C[MAXK];
std::vector <int_pair> ADC[MAXN];

inline void AddEdge(int x, int y, int w) {
    ADC[x].push_back({y, w});
    ADC[y].push_back({x, w});
}

std::priority_queue <int_pair, std::vector <int_pair>, std::greater <int_pair>> PQ;
int Dist[MAXK][MAXN];

void Dijkstra(int Dist[], int start) {
    for (int i=1; i<=N; ++i)
        Dist[i] = inf;
    Dist[start] = 0;
    PQ.push({0, start});

    int_pair Top;
    while (!PQ.empty()) {
        Top = PQ.top();
        PQ.pop();

        if (Top.first > Dist[Top.second]) continue;
        for (auto Edge:ADC[Top.second])
            if (Dist[Edge.first] > Top.first + Edge.second) {
                Dist[Edge.first] = Top.first + Edge.second;
                PQ.push({Dist[Edge.first], Edge.first});
            }
    }
}

std::ifstream In("ubuntzei.in");
std::ofstream Out("ubuntzei.out");

int Ans, DP[MAXBITS][MAXK];
void Dyn() {
    for (int i=0, j; i<MAXBITS; ++i)
        for (j=0; j<MAXK; ++j)
            DP[i][j] = inf;

    for (int i=0; i<K; ++i)
        DP[1<<i][i] = Dist[0][i];

    Ans = inf;
    int mask = (1<<K)-1;
    for (int bits=2, i, j; bits<=mask; ++bits) {
        for (i=1; i<K; ++i) {
            if (bits & (1<<i)) {
                for (j=0; j<K; ++j) {
                    if (bits & (1<<j)) {
                        DP[bits][i] = std::min(DP[bits][i], DP[bits ^ (1<<i)][j] + Dist[j][C[i]]);
                    }
                }
            }
        }
    }   Ans = DP[mask][K-1];
}

void Citire() {
    In >> N >> M >> K;
    C[0] = 1; C[K+1] = N;
    for (int i=1; i<=K; ++i)
        In >> C[i];
    K += 2;
    for (int i=0, x, y, w; i<M; ++i)
        In >> x >> y >> w, AddEdge(x, y, w);
}

void Rezolvare() {
    for (int i=0; i<K; ++i)
        Dijkstra(Dist[i], C[i]);
    Dyn();

    Out << Ans << '\n';
}

int main()
{
    Citire();
    Rezolvare();

    return 0;
}