Cod sursa(job #2017521)

Utilizator giotoPopescu Ioan gioto Data 1 septembrie 2017 15:41:58
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, k;
int c[20];
long long dist[20][2005], d[131080][17];
const long long INF = 200000000000000000;
vector <pair <int, int> > v[1005];
priority_queue <pair <int, int> > q;
inline void dijkstra(int i, long long dist[]){
    int nod = c[i];
    for(int j = 1; j <= n ; ++j)
        dist[j] = INF;
    dist[nod] = 0;
    q.push(make_pair(0, nod));
    while(!q.empty()){
        nod = q.top().second;
        q.pop();
        for(auto it : v[nod]){
            if(dist[it.first] > dist[nod] + it.second){
                dist[it.first] = dist[nod] + it.second;
                q.push(make_pair(-dist[it.first], it.first));
            }
        }
    }
}
int main(){
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    scanf("%d%d", &n, &m);
    scanf("%d", &k);
    for(int i = 1; i <= k ; ++i)
        scanf("%d", &c[i]);
    int x, y, cost;
    for(int i = 1; i <= m ; ++i){
        scanf("%d%d%d", &x, &y, &cost);
        v[x].push_back(make_pair(y, cost));
        v[y].push_back(make_pair(x, cost));
    }
    c[0] = 1;
    c[++k] = n;
    for(int i = 0; i <= k ; ++i)
        dijkstra(i, dist[i]);
    if(k == 0){
        printf("%d", dist[0][n]);
        return 0;
    }
    for(int i = 1; i < (1 << (k + 1)) ; ++i)
        for(int j = 0; j <= k ; ++j)
            d[i][j] = INF;
    d[1][0] = 0;
    for(int mask = 1; mask < (1 << (k + 1)) ; ++mask){
        for(int i = 0; i <= k ; ++i){
            if(d[mask][i] == INF) continue ;
            if((1 << i) & mask)
            for(int j = 0; j <= k ; ++j){
                if((1 << j) & mask) continue ;
                d[mask + (1 << j)][j] = min(d[mask + (1 << j)][j], d[mask][i] + dist[i][c[j]]);
            }
        }
    }
    printf("%lld", d[(1 << (k + 1)) - 1][k]);
    return 0;
}