Cod sursa(job #2081743)

Utilizator CammieCamelia Lazar Cammie Data 5 decembrie 2017 08:39:13
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
#include <cstring>

#define inf 0x3f3f3f3f
#define MAXK 17
#define MAXN 2005

using namespace std;

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

struct str{
    int nod, c;

    bool operator < (const str& other) const {
        return c < other.c;
    }
};

priority_queue <str> Q;
vector <str> graph[MAXN];

int n, m, k, u[MAXN], cost[MAXK][MAXN];
int dp[(1 << MAXK) - 1][MAXK], nn, mask;

inline void Read() {
    int x, y, z;

    fin >> n >> m;
    fin >> k;

    for (int i = 1; i <= k; i++) {
        fin >> u[i];
    }

    for (int i = 1; i <= m; i++) {
        fin >> x >> y >> z;

        graph[x].push_back({y, z});
        graph[y].push_back({x, z});
    }
}

inline void Dijkstra(int poz) {
    int z, cc;
    Q.push({u[poz], 0});
    cost[poz][u[poz]] = 0;

    while (!Q.empty()) {
        z = Q.top().nod;
        cc = Q.top().c;

        Q.pop();

        if (cc != cost[poz][z])
            continue;

        for (auto x : graph[z]) {
            if (cost[poz][x.nod] > cost[poz][z] + x.c) {
                cost[poz][x.nod] = cost[poz][z] + x.c;

                Q.push({x.nod, cost[poz][x.nod]});
            }
        }
    }
}

inline void Solve() {
    memset(cost, inf, sizeof(cost));

    for (int i = 1; i <= k; i++) {
        Dijkstra(i);
    }

    nn = (1 << k) - 1;
    memset(dp, inf, sizeof(dp));
    dp[1][1] = cost[1][1];

    for (int i = 1; i <= nn; i++) {
        for (int j = 0; j < k; j++) {
            if (i & (1 << j)) {
                mask = i - (1 << j);

                for (int q = 0; q < k; q++) {
                    if (mask & (1 << q))
                        dp[i][j + 1] = min(dp[i][j + 1], dp[mask][q] + cost[j + 1][u[q]]);
                }
            }
        }
    }

    int minim = INT_MAX;

    for (int i = 0; i < k; i++) {
        if (dp[nn][i + 1] + cost[i + 1][n] < minim)
            minim = dp[nn][i + 1] + cost[i + 1][n];
    }

    fout << minim;
}

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

    fin.close(); fout.close(); return 0;
}