Cod sursa(job #1571564)

Utilizator blackoddAxinie Razvan blackodd Data 18 ianuarie 2016 10:22:53
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

#define MaxN 2001
#define MaxK 16
#define INF 0x3f3f3f3f

int n, m, k;
vector<int> C(MaxK);
vector<pair<int,int> >G[MaxN];
vector<int> D[MaxK], d;
int dp[1 << MaxK][MaxK];


void Read();
void Solve();
void Dijkstra(int S, vector<int>& d);

int main()
{
    Read();
    Solve();

    fin.close();
    fout.close();
    return 0;
}

void Solve() {

    Dijkstra(1,d);

    if ( k == 0 ) {
        fout << d[n] << ' ';
        return 0;
    }

    for ( int i = 0; i < k; ++i )
        Dijkstra(C[i], D[i]);

    for ( int i = 0; i < k; ++i )
        dp[(1 << i)][i] = d[C[i]];

    for ( int i = 1; i < (1 << k ); ++i )
        for ( int j = 0; j < k; ++j )
            if ( i & (1 << j) )
                for ( int kappa = 0; kappa < k; ++kappa )
                    if ( !(i & (1 << kappa)) )
                        dp[i | (1 << kappa)][kappa] = min(dp[i | (1 << kappa)][kappa], dp[i][j] + D[j][C[kappa]]);

    int rez = INF;

    for ( int i = 0; i < k; ++i )
        rez = min(rez, dp[(1 << k) - 1][i] + D[i][n]);

    fout << rez;

}

void Dijkstra(int S, vector<int>& d){

    d = vector<int>(n + 1, INF);

    priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > Q;

    Q.push({0,S});
    d[S] = 0;

    while(Q.size()) {

        int nod = Q.top().second;
        int dist = Q.top().first;
        Q.pop();

        for ( const auto &y : G[nod] ) {

            int vecin = y.first;
            int cost  = y.second;

            if ( d[vecin] > d[nod] + cost ) {
                d[vecin] = d[nod] + cost;
                Q.push({d[vecin], vecin});
            }
        }
    }


}

void Read() {

    fin >> n >> m;

    fin >> k;

    for ( int i = 0; i < k; ++i )
        fin >> C[i];

    for ( int i = 1, x, y, z; i <= m; ++i ) {
        fin >> x >> y >> z;
        G[x].push_back({y,z});
        G[y].push_back({x,z});
    }

    for ( int i = 0; i < (1 << MaxK); ++i )
        for ( int j = 0; j < MaxK; ++j )
            dp[i][j] = INF;
}