Cod sursa(job #1772927)

Utilizator VladTiberiuMihailescu Vlad Tiberiu VladTiberiu Data 7 octombrie 2016 11:43:44
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <bits/stdc++.h>

#define NMax 2002
#define KMax 18
#define INF (1<<30) - 1
#define INFll (1<<62) - 1
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int n,m,k,x,y,w,ans;
int c[NMax],preLog[NMax];
int dist[NMax];
int Dind[KMax][KMax],best[(1<<16)][KMax];
vector<pair<int,int> > G[NMax];
queue<int> q;

void bf(int nod){
    for(int i = 1; i <= n; ++i)
        dist[i] = INF;
    q.push(nod);
    dist[nod] = 0;
    while(!q.empty()){
        int nod = q.front();
        q.pop();
        for(int i = 0; i < G[nod].size(); ++i){
            if(dist[G[nod][i].first] > dist[nod] + G[nod][i].second){
                dist[G[nod][i].first] = dist[nod] + G[nod][i].second;
                q.push(G[nod][i].first);
            }
        }
    }
}
int main(){

    f >> n >> m >> k;
    for(int i = 0; i < k; ++i){
        f >> c[i];
    }
    for(int i = 1; i <= m; ++i){
        f >> x >> y >> w;
        G[x].push_back(make_pair(y,w));
        G[y].push_back(make_pair(x,w));
    }
    c[k] = 1;
    c[k + 1] = n;
    for(int iind = 0; iind <= k + 1; ++iind){
        bf(c[iind]);
        for(int jind = 0; jind <= k + 1; ++jind){
            Dind[iind][jind] = dist[c[jind]];
        }
    }
    if(k == 0){
        g << Dind[k][k + 1] << '\n';
        return 0;
    }
    ///best[i][j] = drumul minim in care ajungem in j(indicele j, nu orasul j)
    ///             cu orasele vizitate descrise de masca de biti
    for(int mask = 1; mask <= (1 << k); ++mask){
        for(int j = 0; j < k; ++j){
            best[mask][j] = INF;
        }
    }
    for(int i = 0; i < k; ++i){
        best[(1 << i)][i] = Dind[k][i];
    }
    for(int mask = 0; mask <= (1 << k); ++mask){

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

            for(int j = 0; j < k; ++j){
                if(!(mask & (1 << j))){
                    best[mask | (1 << j)][j] = min(best[mask|(1 << j)][j],best[mask][i] + Dind[i][j]);
                }
            }
        }
    }
    ans = INF;
    for(int i = 0; i < k; ++i){
        ans = min(ans,best[(1 << k) - 1][i] + Dind[i][k + 1]);
    }
    g << ans << '\n';
}