Cod sursa(job #2131728)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 14 februarie 2018 21:47:59
Problema Ubuntzei Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#define DIM 2002
#define LG 20
#define INF 2e9
#define f first
#define s second

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], viz[DIM], cost, dinit[DIM], dfinal[DIM];

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

class compare{
public:
    bool operator() (int a, int b){
        return d[a] < d[b];
    }
};

multiset <int, compare> s;

void resetviz(){
    for(int i = 1; i <= n; ++ i)
        viz[i] = 0;
}

void dijkstra(int NOD){
    int valnod = NOD;
    if(NOD != 1)
        NOD = c[NOD];
    s.clear();
    s.insert(NOD);
    resetviz();
    for(int i = 1; i <= n; ++ i)
        d[i] = INF;
    d[NOD] = 0;
    for(int i = 1; i <= n && !s.empty(); ++ i){
        int nod = *s.begin();
        s.erase(s.begin());
        viz[nod] = 1;
        for(int j = 0; j < graf[nod].size(); ++ j){
            int nodc = graf[nod][j].f;
            int cost = graf[nod][j].s;
            if(viz[nodc]) continue;
            int val = d[nod] + cost;
            if(val < d[nodc]){
                if(d[nodc] != INF && !s.empty())
                    s.erase(s.find(nodc));
                d[nodc] = val;
                s.insert(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]];
    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(1);
        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;
}