Cod sursa(job #2033594)

Utilizator MihaelaCismaruMihaela Cismaru MihaelaCismaru Data 7 octombrie 2017 01:02:08
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.27 kb
#include<fstream>
#include<vector>
#include<bitset>
using namespace std;
ifstream in("ubuntuzei.in");
ofstream out("ubuntuzei.out");
const int DIM = 2001;
int cost[DIM][DIM],d[DIM],pozitie[DIM],prieteni[DIM],dp[DIM][DIM];
bitset<DIM>ex;
vector<pair<int,int> >v[DIM];
int sz,n,m,k,a,b,c,knot,val;
struct str{
    int nod,val;
}heap[1001];
void up (int p) {
    while (p/2 >= 1 && heap[p].val < heap[p/2].val){
        swap(pozitie[heap[p].nod], pozitie[heap[p/2].nod]);
        swap(heap[p],heap[p/2]);
        p /= 2;
    }
    return;
}
void down (int p) {
    while (p * 2 <= sz) {
        int t = p * 2;
        if (heap[t+1].val < heap[t].val) {
            t ++;
        }
        if(heap[t].val < heap[p].val){
            swap(pozitie[heap[p].nod],pozitie[heap[t].nod]);
            swap(heap[t], heap[p]);
            p = t;
        }
        else{
            return;
        }
    }
    return;
}
void elimina(){
    ex[heap[1].nod] = 1;
    swap(heap[1],heap[sz]);
    swap(pozitie[heap[1].nod], pozitie[heap[sz].nod]);
    down(1);
    sz--;
    return;
}
int main() {
    in >> n >> m;
    in >>k;
    k += 2; prieteni[0] = 0; prieteni[k-1] = n-1;
    for (int i = 1; i < k-1; i++) {
        in >> prieteni[i];
        prieteni[i] -= 1;
    }
    for (int i = 1; i <= m; i ++) {
        in >> a >> b >> c;
        v[a-1].push_back(make_pair(b-1,c));
        v[b-1].push_back(make_pair(a-1,c));
    }
    for (int i = 0; i < k; i ++){
        knot = prieteni[i];
        heap[1].nod = knot;
        heap[1].val = 0;
        pozitie[knot] = 1;
        sz = 1;
        for (int j = 0; j < n; j ++) {
            if (knot == j) {
                continue;
            }
            heap[++sz].nod = j ;
            heap[ sz ].val =1e9;
            pozitie[j] = sz;
        }
        for (int j = 0; j < n; j ++){
            ex[j] = 0;
        }
        for (int j = 1; j <= n; j ++) {
            knot = heap[1].nod;
            val = heap[1].val;
            elimina();
            for (int h = 0; h < v[knot].size(); h ++) {
                if (ex[ v[knot][h].first ] == 0){
                    heap[ pozitie[ v[knot][h].first ] ].val = min (heap[ pozitie[ v[knot][h].first ] ].val, val + v[knot][h].second );
                    up (pozitie[v[knot][h].first]); down (pozitie[v[knot][h].first]);
                }
            }
        }
        for (int j = 1; j <= k; j ++) {
            d[ heap[j].nod ] = heap[j].val;
        }
        for (int j = 0; j < k; j ++){
            if ( j != i ){
                cost[i][j] = d[prieteni[j]];
            }
        }
    }

    for (int i = 0; i < (1<<k); i ++) {
        for (int j = 0; j < k; j ++) {
            dp[i][j] = 1e9;
        }
    }
    dp[1][0] = 0;
    for (int stare = 0; stare < (1<<k); stare ++) {
        for (int nod = 0; nod < k; nod ++) {
            if (dp[stare][nod] == 1e9){
                continue;
            }
            for (int h = 0; h < k; h ++) {
                if (nod == h || (stare>>h) % 2 == 1) {
                    continue;
                }
                dp[stare+(1<<h)][h] = min(dp[stare+(1<<h)][h], dp[stare][nod] + cost[nod][h] );
            }
        }
    }
    out << dp[ (1<<k) - 1 ][k-1];
    return 0;
}