Cod sursa(job #2173309)

Utilizator mariakKapros Maria mariak Data 15 martie 2018 21:35:31
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <bits/stdc++.h>
#define pii pair <int, int>
#define f first
#define s second
#define pb push_back
#define mp make_pair

FILE *fin  = freopen("ubuntzei.in", "r", stdin);
FILE *Fout = freopen("ubuntzei.out", "w", stdout);

using namespace std;
const int Nmax = 2e3+5;
const int Kmax = 17;
const int inf = 1e9;

/*-------Data-------*/
int n, m, k;
int source, sink;
vector <pii> G[Nmax];

/*------New Graph------*/
vector <pii> nG[Kmax];
int idx[Nmax], who[Kmax];

/*------Dijkstra------*/
struct comp{
    bool operator () (const pii &a, const pii &b)const{
        a.s > b.s;
    }
};
int d[Nmax];

struct New{
    int x, y, z;
    bool operator < (const New &oth) const{
        return z > oth.z;
    }
};
priority_queue < New, vector<New> > q;
int ans[Kmax][1 << Kmax];

void Read(){
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 0; i < k; ++ i){
        int u; scanf("%d", &u);
        idx[u] = i; who[i] = u;
    }
    source = k; sink = k + 1;
    idx[1] = source; idx[n] = sink;
    who[source] = 1; who[sink] = n;

    for(int i = 0; i < m; ++ i){
        int u, v, cost;
        scanf("%d%d%d", &u, &v, &cost);
        G[u].pb(mp(v, cost));
        G[v].pb(mp(u, cost));
    }
}

void Dijk_G(int root){
    for(int i = 1; i <= n; ++ i) d[i]=inf;
    d[root] = 0; q.push(New{root, 0, 0});

    while(!q.empty()){
        New node = q.top();
        q.pop();

        if(d[node.x] < node.z) continue;
        for(pii son : G[node.x])
            if(node.z + son.s < d[son.f]){
                d[son.f] = node.z + son.s;
                q.push(New{son.f, 0, d[son.f]});
            }
    }
}

void Dijk_nG(){ // Dijkstra on new Graph V = {node, state}
    for(int node = 0; node <= sink; ++ node)
        for(int state = 0; state <= (1 << k); ++ state)
            ans[node][state] = inf;
    ans[source][0] = 0;
    q.push(New{source, 0, 0});

    while(!q.empty()){
        New node = q.top();
        q.pop();

        if(ans[node.x][node.y] < node.z)
            continue;

        for(pii son : nG[node.x]){
            // already visited in node's state
            if((1 << son.f) & node.y) continue;

            int state = node.y;
            if(son.f != source && son.f != sink)
                state |= (1 << son.f);

            if(node.z + son.s < ans[son.f][state]){
                ans[son.f][state] = node.z + son.s;
                q.push(New{son.f, state, ans[son.f][state]});
            }
        }
    }
}

void Solve(){
    /*-----Create New Graph------*/
    for(int i = 0; i < sink; ++ i){
        Dijk_G(who[i]);
        for(int j = 0; j <= sink; ++ j)
            if(j != i)
                nG[i].push_back(mp(j, d[who[j]]));
    }
    Dijk_nG();
}

int main(){
    Read();
    Solve();
    printf("%d\n", ans[sink][(1 << k)-1]);
    return 0;
}