Cod sursa(job #2369071)

Utilizator IOI_MDA_003Sebastian Chicu IOI_MDA_003 Data 5 martie 2019 20:58:31
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <bits/stdc++.h>
#define pii pair<int, int>
#define x first
#define y second

using namespace std;

ifstream fin ("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int N_MAX = 2000 + 5;
const int K_MAX = 15 + 5;
const int INF = 0x3f3f3f3f;

int c[K_MAX], k, n, m;
int dist[K_MAX][N_MAX];
int qwee[K_MAX][K_MAX];
int dp[(1<<16) + 5][K_MAX];

priority_queue<pii, vector<pii >, greater<pii> > q;
vector<pii> vec[N_MAX];

bool isbit(int n, int poz){
    int mask = (1<<poz);
    return (n&mask);
}

void setbit(int &n, int poz, bool bit){
    int mask = (1<<poz);
    if(bit)
        n = (n|mask);
    else
        n = (n^mask);
}

void disjkstra(int kstart){
    int nstart = c[kstart];
    dist[kstart][nstart] = 0;
    q.push({0, nstart});
    while(!q.empty()){
        int nod = q.top().y;
        int cst = q.top().x;
        q.pop();

        if(cst != dist[kstart][nod])
            continue;

        for(auto v : vec[nod])
            if(dist[kstart][v.x] > dist[kstart][nod] + v.y){
                dist[kstart][v.x] = dist[kstart][nod] + v.y;
                q.push({dist[kstart][v.x], v.x});
            }
    }

    for(int i = 0; i <=k; ++i)
        qwee[kstart][i] = dist[kstart][c[i]];
}

int main()
{
    fin >> n >> m;
    fin >> k;
    for(int i = 1; i <=k; ++i)
        fin >> c[k];
    c[0] = 1; c[++k] = n;

    while(m--){
        int aa, bb, cc;
        fin >> aa >> bb >> cc;
        vec[aa].push_back({bb,cc});
        vec[bb].push_back({aa,cc});
    }

    for(int i = 0; i <=k; ++i)
        for(int j = 0; j <=n; ++j)
            dist[i][j] = INF;

    for(int mask = 0; mask <= (1<<(k+1)) - 1; ++mask)
        for(int i = 0; i <= k; ++i)
            dp[mask][i] = INF;


    for(int i = 0; i <= k; ++i)
        disjkstra(i);


    dp[1][0] = 0;
    for(int mask = 0; mask <= (1<<(k+1)) - 1; ++mask){
//        for(int i = 0; i <=k; ++i)
//            cout << dp[mask][i] << " ";
//        cout << endl;
        for(int i = 0; i <=k; ++i)
            for(int j = 0; j <=k; ++j)
                if(isbit(mask, i) and !isbit(mask, j)){
                    dp[mask + (1<<j)][j] = min(dp[mask + (1<<j)][j], dp[mask][i] + qwee[i][j]);
                    //cout << dp[mask + (1<<j)][j] << " " << dp[mask][i] + qwee[i][j] << "\n";
                    //cout << mask << " " << mask + (1<<j) << " " << i << " " << j << " " << qwee[i][j] << "\n";
                }
    }

    fout << dp[(1<<(k+1))-1][k];

    return 0;
}

//grija mare la zerouri
//critical error la costuri K_MAX in loc de N_MAX