Cod sursa(job #1250570)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 28 octombrie 2014 12:44:41
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
/// Craciun Catalin
///  Ubuntzei
///   OJI 2011
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

#define NMax 2030
#define mp(a,b) make_pair(a,b)
#define inf 1<<30

using namespace std;

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

int n, m, k, MIN;
int father[NMax];
int dist_tmp[NMax];
int c[NMax];
int dist_min[ 16 ][ NMax ];
int DP[ 1 << 16 ][ 16 ];
vector < pair <int, int> > g[NMax];
queue <int> q;

void read() {

    in>>n>>m>>k;

    for(int i=1; i<=k; ++i)
        in>>c[i];

    while( m-- ) {
        int x, y, cost;
        in>>x>>y>>cost;
        g[x].push_back(mp(y, cost));
        g[y].push_back(mp(x, cost));
    }
}

void dijkstra(int source) {
    q.push( source );

    for(int i=1; i<=n; ++i)
        dist_tmp[i] = inf;
    dist_tmp[ source ] = 0;

    while( !q.empty() ) {
        int node = q.front();
        q.pop();

        for( vector <pair <int, int> > :: iterator it = g[node].begin(); it != g[node].end(); ++it)
            if( dist_tmp[(*it).first] > dist_tmp[node] + (*it).second) {
                dist_tmp[(*it).first] = dist_tmp[node] + (*it).second;
                q.push((*it).first);
            }
    }
}

void solve() {

    if( !k ) {
        dijkstra( 1 );
        out<<dist_tmp[n]<<'\n';
    } else {
        c[ 0 ] = 1;
        for(int i = 0; i <= k; ++i) {
            dijkstra( c[i] );
            for(int j = 0; j <= k; ++j)
                dist_min[i][j] = dist_tmp[ c[j] ];
            dist_min[i][k + 1] = dist_tmp[ n ];
        }

        int lim = ( 1 << k );
        for(int mask = 0; mask < lim; ++mask)
            for(int i = 0; i <= k; ++i)
                DP[ mask ][ i ] = inf;

        DP[ 0 ][ 0 ] = 0;

        for(int mask = 1; mask < lim; ++mask)
            for(int i = 0; i < k; ++i)
                if( mask & ( 1 << i  )) {
                    int mask2 = mask - (1 << i);
                    for(int j = 0; j <= k; ++j)
                        DP[ mask ][ i + 1 ] = min( DP[mask][ i + 1 ], DP[ mask2 ][ j ] + dist_min[ j ][ i + 1 ]);
                }
        int sol = inf;

        for(int i = 1; i <= k; ++i)
            sol = min( sol, DP[ lim - 1 ][ i ] + dist_min[ i ][ k + 1 ]);

        out<<sol<<'\n';
    }
}

int main() {

    read();
    solve();

    in.close(); out.close();

    return 0;
}