Cod sursa(job #2360540)

Utilizator nurof3nCioc Alex-Andrei nurof3n Data 1 martie 2019 21:51:50
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int N_MAX = 2001;
const int K_MAX = 16;
const int INF = 1000000000;

struct muchie {
    int y, cost;
};

int N, M, K;
vector<muchie> Edges[N_MAX];
int fren[K_MAX], mindist[K_MAX][K_MAX];
int dp[(1 << K_MAX)][K_MAX];

struct comp {
    bool operator() (const muchie &a, const muchie &b) {
        return a.cost > b.cost;
    }
};
priority_queue<muchie, vector<muchie>, comp> Q;
int D[N_MAX];
bool viz[N_MAX];

void dijkstra(int start) {
    for(int i = 1; i <= N; ++i)
        D[i] = INF, viz[i] = false;
    D[start] = 0;
    Q.push({start, D[start]});

    while (!Q.empty()) {
        int x = Q.top().y;
        Q.pop();
        if (viz[x])
            continue;
        for (auto m : Edges[x]) {
            int y = m.y;
            int cost = m.cost;
            if (D[x] + cost < D[y]) {
                D[y] = D[x] + cost;
                if(!viz[y])
                    Q.push({y, D[y]});
            }
        }
        viz[x] = true;
    }
}

int main() {
    in >> N >> M >> K;
    int x, y, cost;
    for(int i = 1; i <= K; ++i)
        in >> fren[i];
    for(int i = 1; i <= M; ++i) {
        in >> x >> y >> cost;
        Edges[x].push_back({y, cost});
        Edges[y].push_back({x, cost});
    }

    if(K == 0) {
        dijkstra(1);
        out << D[N];
        return 0;
    }

    fren[0] = 1;
    for(int start = 0; start <= K; ++start) {
        dijkstra(fren[start]);
        for(int i = 0; i <= K; ++i)
            mindist[start][i] = D[fren[i]];
        mindist[start][K + 1] = D[N];
    }

    int lim = (1 << K) - 1;
    for(int subm = 0; subm <= lim; ++subm)
        for(int j = 0; j <= K; ++j)
            dp[subm][j] = INF;
    dp[0][0] = 0;

    for(int subm = 1; subm <= lim; ++subm)
        for(int bit = 0; bit < K; ++bit)
            if(subm & (1 << bit)) {
                int subm2 = subm - (1 << bit);
                for(int i = 0; i <= K; ++i)
                    dp[subm][bit + 1] = min(dp[subm][bit + 1], dp[subm2][i] + mindist[i][bit + 1]);
            }

    int sol = INF;
    for(int i = 1; i <= K; ++i)
        sol = min(sol, dp[lim][i] + mindist[i][K + 1]);
    out << sol;

    return 0;
}