Cod sursa(job #2489580)

Utilizator IoanaDraganescuIoana Draganescu IoanaDraganescu Data 8 noiembrie 2019 23:59:22
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

const int Nmax = 2005, Kmax = 17, inf = 0x3f3f3f3f;

struct Edge{
    int nod, cost;
    Edge(int n, int c) : nod(n), cost(c) {}
};
vector <Edge> g[Nmax + 5];
struct Heap{
    int nod, cost;
    Heap(int n, int c) : nod(n), cost(c) {}
    bool operator < (const Heap &other) const{
        return cost > other.cost;
    }
};
priority_queue <Heap> q;
int n, m, k, d[Nmax + 5], C[Kmax + 5], c[(1 << Kmax) + 5][Kmax + 5], a[Kmax + 5][Kmax + 5];

void Read(){
    fin >> n >> m >> k;
    C[0] = 1;
    C[k + 1] = n;
    for (int i = 1; i <= k; i++)
        fin >> C[i];
    for (int i = 1; i <= m; i++){
        int x, y, z;
        fin >> x >> y >> z;
        g[x].push_back({y, z});
        g[y].push_back({x, z});
    }
}

void Dijkstra(int Nod, int ind){
    memset(d, inf, sizeof d);
    q.emplace(Nod, 0);
    d[Nod] = 0;
    while (!q.empty()){
        int nod = q.top().nod, cost = q.top().cost;
        q.pop();
        if (d[nod] != cost)
            continue;
        for (auto i : g[nod])
            if (d[i.nod] > cost + i.cost){
                d[i.nod] = cost + i.cost;
                q.emplace(i.nod, d[i.nod]);
            }
    }
    for (int i = 0; i <= k + 1; i++)
        a[ind][i] = a[i][ind] = d[C[i]];
}

void Solve(){
    for (int i = 0; i <= k; i++)
        Dijkstra(C[i], i);
    k += 2;
    for (int conf = 0; conf < (1 << k); conf++)
        for (int j = 0; j < k; j++)
            c[conf][j] = inf;
    c[1][0] = 0;
    for (int conf = 1; conf < (1 << k); conf++)
        for (int j = 0; j < k; j++)
            if (conf & (1 << j))
                for (int vecin = 0; vecin < k; vecin++)
                    if (a[vecin][j] && conf & (1 << vecin))
                        c[conf][j] = min(c[conf][j], c[conf - (1 << j)][vecin] + a[j][vecin]);

}

void Print(){
    fout << c[(1 << k) - 1][k - 1] << '\n';
}

int main(){
    Read();
    Solve();
    Print();
    return 0;
}