Cod sursa(job #2070530)

Utilizator alexandra_udristoiuUdristoiu Alexandra Maria alexandra_udristoiu Data 19 noiembrie 2017 17:39:57
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include<fstream>
#include<vector>
#define INF 10000000000LL
using namespace std;
int n, m, k, i, j, ii, x, y, cost, cp;
int w[18], h[760], poz[760], ff[760], num[(1 << 16) + 2], viz[760];
long long d[(1 << 16) + 2][16], d2[760], dist[18][18][18], sol;
struct str{
    int x, cp, cost;
};
vector<str> v[760];
ifstream fin("gather.in");
ofstream fout("gather.out");
void upd(int pos){
    int c = pos, p = c / 2;
    while(p > 0 && d2[ h[p] ] > d2[ 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 && d2[ h[c + 1] ] < d2[ h[c] ]){
            c++;
        }
        if(d2[ h[c] ] < d2[ 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 cmax, int srs){
    int i, j, nod, vecin;
    for(i = 1; i <= n; i++){
        poz[i] = h[i] = i;
        d2[i] = INF;
        viz[i] = 0;
    }
    d2[srs] = 0;
    upd(poz[srs]);
    for(i = 1; i <= n; i++){
        nod = h[1];
        if(ff[nod] != -1){
            dist[cmax][ ff[srs] ][ ff[nod] ] = d2[nod];
        }
        viz[nod] = 1;
        for(j = 0; j < v[nod].size(); j++){
            if(v[nod][j].cp < cmax){
                continue;
            }
            vecin = v[nod][j].x;
            if(viz[vecin] == 0 && d2[vecin] > d2[nod] + v[nod][j].cost){
                d2[vecin] = d2[nod] + v[nod][j].cost;
                upd(poz[vecin]);
            }
        }
        viz[nod] = 1;
        d2[nod] = INF + 10;
        elim();
    }
}
int main(){
    fin>> k >> n >> m;
    for(i = 1; i <= n; i++){
        ff[i] = -1;
    }
    ff[1] = 0;
    for(i = 1; i <= k; i++){
        fin>> w[i];
        ff[ w[i] ] = i;
    }
    w[0] = 1;
    for(i = 1; i <= m; i++){
        fin>> x >> y >> cost >> cp;
        v[x].push_back( {y, cp, cost} );
        v[y].push_back( {x, cp, cost} );
    }
    for(i = 0; i <= k; i++){
        for(j = 0; j <= k; j++){
            djikstra(i, w[j]);
        }
    }
    k++;
    for(i = 1; i < (1 << k); i++){
        num[i] = num[i / 2] + i % 2;
    }
    for(i = 0; i < k; i++){
        d[0][i] = d[1][i] = INF;
    }
    d[1][0] = 0;
    for(ii = 2; ii < (1 << k); ii++){
        d[ii][0] = INF;
        for(i = 1; i < k; i++){
            d[ii][i] = INF;
            if( ( (ii >> i) & 1) == 0){
                continue;
            }
            for(j = 0; j < k; j++){
                d[ii][i] = min(d[ii][i], d[ii - (1 << i)][j] + dist[ num[ii] - 2][i][j] * (num[ii] - 1) );
            }
        }
    }
    sol = INF;
    for(i = 1; i < k; i++){
        sol = min(sol, d[(1 << k) - 1][i]);
    }
    fout<< sol <<"\n";
}