Cod sursa(job #1254483)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 2 noiembrie 2014 19:54:22
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 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 B[16];
vector < pair <int, int> > g[NMax];
queue <int> q;
int sol = inf;

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 foundSolution() {

    int len = 0;
    for (int i=0;i<k;i++) {
        len += dist_min[c[B[i]]][c[B[i+1]]];
    }

    len += dist_min[c[B[k]]][n];

    sol = min(sol, len);
}

void bkt(int p) {

    if (p == k+1)
        foundSolution();
    else {
        for (int j=1;j<=k;j++) {
            bool eligible = true;
            for (int i=1;i<p && eligible;i++) {
                if (B[i] == j)
                    eligible = false;
            }

            if (eligible) {
                B[p] = j;
                bkt(p+1);
            }
        }
    }
}

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 = 1; j <= n; ++j)
                dist_min[c[i]][c[j]] = dist_tmp[ c[j] ];
            dist_min[c[i]][n] = dist_tmp[ n ];
        }

        bkt(1);

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

int main() {

    read();
    solve();

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

    return 0;
}