Cod sursa(job #2131936)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 15 februarie 2018 10:16:32
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define DIM 2002
#define LG 20
#define INF 2e9
#define f first


using namespace std;

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

int n, m, k, x, y, c[LG], dp[(1<<16)][LG], dist[LG][LG], d[DIM], cost, dinit[DIM], dfinal[DIM];

vector <pair<int, int> > graf[DIM];

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > h;

void dijkstra(int NOD){
    int valnod = NOD;
    if(NOD != INF)
        NOD = c[NOD];
    if(NOD == INF)
        NOD = 1;
    h.push(make_pair(0, NOD));
    for(int i = 1; i <= n; ++ i)
        d[i] = INF;
    d[NOD] = 0;
    while(!h.empty()){
        int nod = h.top().second;
        int COST = h.top().f;
        h.pop();
        if(COST != d[nod])
            continue;
        for(int j = 0; j < graf[nod].size(); ++ j){
            int nodc = graf[nod][j].f;
            int cost = graf[nod][j].second;
            int val = d[nod] + cost;
            if(val < d[nodc]){
                d[nodc] = val;
                h.push(make_pair(d[nodc], nodc));
            }
        }
//        for(set<int, compare>::iterator it = s.begin(); it != s.end(); ++ it){
//            out<<*it<<" ";
//        }
//        out<<'\n';
    }
    for(int i = 0; i < k; ++ i)
        dist[valnod][i] = d[c[i]];
    if(valnod != INF){
        dinit[valnod] = d[1];
        dfinal[valnod] = d[n];
    }
}

bool test(int a, int b){
    return (a & (1<<b));
}

int main() {
    in>>n>>m;
    in>>k;
    for(int i = 0; i < k; ++ i)
        in>>c[i];
    for(int i = 1; i <= m; ++ i){
        in>>x>>y>>cost;
        graf[x].push_back(make_pair(y, cost));
        graf[y].push_back(make_pair(x, cost));
    }
    if(k == 0){
        dijkstra(INF);
        out<<d[n];
        return 0;
    }
    for(int i = 0; i < k; ++ i)
        dijkstra(i);
//    for(int i = 0; i < k; ++ i, out<<'\n')
//        for(int j = 0; j < k; ++ j)
//            out<<dist[i][j]<<' ';
    int PUT = (1<<k);
    for(int i = 0; i < PUT; ++ i)
        for(int j = 0; j < k; ++ j)
            dp[i][j] = INF;
    for(int i = 0; i < k; ++ i)
        dp[(1<<i)][i] = dinit[i];
    for(int i = 1; i < PUT; ++ i){
        for(int j = 0; j < k; ++ j){
            if(test(i, j)){
                for(int l = 0; l < k; ++ l){
                    if(!test(i, l)){
                        dp[i + (1<<l)][l] = min(dp[i + (1<<l)][l], dp[i][j] + dist[j][l]);
                    }
                }
            }
        }
    }
    int minim = INF;
    for(int i = 0; i < k; ++ i)
        minim = min(minim, dp[PUT - 1][i] + dfinal[i]);
    out<<minim;
    return 0;
}