Cod sursa(job #1904421)

Utilizator alexandra_udristoiuUdristoiu Alexandra Maria alexandra_udristoiu Data 5 martie 2017 15:35:38
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include<fstream>
#include<vector>
#define f first
#define s second
#define INF 1000000000
using namespace std;
int n, m, k, i, x, y, z, j, ii, jj, ii2, sol;
int dp[(1 << 15)][15], w[17], d[16][2005], di[2005], h[2005], poz[2005], viz[2005], ff[2005];
vector< pair<int, int> > v[2005];
vector<int> p[(1 << 15)];
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
void upd(int pos){
    int c = pos, p = c / 2;
    while(p > 0 && di[ h[p] ] > di[ h[c] ]){
        swap(h[p], h[c]);
        poz[ h[p] ] = p;
        poz[ h[c] ] = c;
        c = p;
        p = c / 2;
    }
}
void elim(){
    int p = 1, c = 2;
    while(c <= n){
        if(c + 1 <= n && di[ h[c] ] > di[ h[c + 1] ]){
            c++;
        }
        if(di[ h[c] ] < di[ h[p] ]){
            swap(h[p], h[c]);
            poz[ h[p] ] = p;
            poz[ h[c] ] = c;
            p = c;
            c = 2 * p;
        }
        else{
            break;
        }
    }
}
void djikstra(int srs, int t){
    for(int i = 1; i <= n; i++){
        viz[i] = 0;
        di[i] = INF;
        h[i] = poz[i] = i;
    }
    di[srs] = 0;
    upd(srs);
    while(di[ h[1] ] != INF){
        int nod = h[1];
        d[t][nod] = di[nod];
        viz[nod] = 1;
        for(int i = 0; i < v[nod].size(); i++){
            int vecin = v[nod][i].f;
            int cost = v[nod][i].s;
            if(viz[vecin] == 0 && di[vecin] > di[nod] + cost){
                di[vecin] = di[nod] + cost;
                upd(poz[vecin]);
            }
        }
        di[nod] = INF;
        elim();
    }
}
int main(){
    fin>> n >> m;
    fin>> k;
    for(i = 0; i < k; i++){
        fin>> w[i];
        ff[ w[i] ] = i;
    }
    for(i = 1; i <= m; i++){
        fin>> x >> y >> z;
        v[x].push_back( make_pair(y, z));
        v[y].push_back( make_pair(x, z) );
    }
    djikstra(1, k);
    for(i = 0; i < k; i++){
        djikstra(w[i], i);
    }
    if(k == 0){
        fout<< d[0][n] <<"\n";
        return 0;
    }
    for(i = 1; i < (1 << k); i++){
        for(j = 0; j < k; j++){
            if( ( (i >> j) & 1) == 1 ){
                p[i].push_back(j);
            }
        }
    }
    for(i = 1; i < (1 << k); i++){
        if(p[i].size() == 1){
            dp[i][ p[i][0] ] = d[k][ w[ p[i][0] ] ];
        }
        else{
            for(j = 0; j < p[i].size(); j++){
                ii = p[i][j];
                dp[i][ii] = INF;
                for(jj = 0; jj < p[i - (1 << ii)].size(); jj++){
                    ii2 = p[i - (1 << ii)][jj];
                    dp[i][ii] = min(dp[i][ii], dp[i - (1 << ii)][ii2] + d[ii2][ w[ii] ]);
                }
            }
        }
    }
    sol = INF;
    for(j = 0; j < k; j++){
        sol = min(sol, dp[(1 << k) - 1][j] + d[j][n]);
    }
    fout<< sol <<"\n";
    return 0;
}