Cod sursa(job #583799)

Utilizator ssergiussSergiu-Ioan Ungur ssergiuss Data 22 aprilie 2011 17:56:22
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <algorithm>
#include <bitset>
#include <cstring>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

const char Input[] = "ubuntzei.in";
const char Output[] = "ubuntzei.out";

const int Inf = 0x3f3f3f3f;
const int MaxB = 32769;
const int MaxN = 2001;
const int MaxK = 17;

int N, M, K, XXX;
int c[MaxK][MaxK], dst[MaxN], loc[MaxK], sol[MaxB][MaxK];
bitset <MaxN> f;
vector < pair <int, int> > v[MaxN];

struct cmp {

    bool operator()( int x, int y ) {

        return dst[x] > dst[y];
    }
};
priority_queue <int, vector <int>, cmp > h;

void BellmanFord( int sursa ) {

    int i, nod;
    vector < pair <int, int> > :: iterator it;

    f.reset();
    memset( dst, Inf, sizeof( dst ) );
    dst[loc[sursa]] = 0;
    h.push( loc[sursa] );
    f[loc[sursa]] = true;

    while( !h.empty() ) {

        nod = h.top();
        h.pop();
        f[nod] = false;

        for( it = v[nod].begin(); it != v[nod].end(); ++it )
            if( dst[nod] + it->second < dst[it->first] ) {

                dst[it->first] = dst[nod] + it->second;
                if( f[it->first] == false ) {

                    h.push( it->first );
                    f[it->first] = true;
                }
            }
    }

    for( i = 0; i <= K + 1; ++i )
        c[sursa][i] = dst[loc[i]];
}

int main() {

    ifstream fin( Input );
    ofstream fout( Output );

    int i, j, k, x, y, z;

    fin >> N >> M >> K;
    for( i = 1; i <= K; ++i )
        fin >> loc[i];
    while( M-- ) {

        fin >> x >> y >> z;
        v[x].push_back( make_pair( y, z ) );
        v[y].push_back( make_pair( x, z ) );
    }

    loc[0] = 1;
    loc[K + 1] = N;
    for( i = 0; i <= K; ++i )
        BellmanFord( i );

    if( !K )
        fout << c[0][K + 1];
    else {

        memset( sol, Inf, sizeof( sol ) );
        for( i = 1; i < (1 << K); ++i )
            for( j = 1; j <= K; ++j )
                if( i & (1 << (j - 1)) ) {

                    if( !(i ^ (1 << (j - 1))) )
                        sol[i][j] = c[0][j];
                    else
                        for( k = 1; k <= K; ++k )
                            if( i & (1 << (k - 1)) )
                                sol[i][j] = min( sol[i][j], sol[i - (1 << (j - 1))][k] + c[k][j] );
                }

        XXX = Inf;
        for( i = 0; i <= K; ++i )
            XXX = min( XXX, sol[(1 << K) - 1][i] + c[i][K + 1] );

//        for( int i = 0; i <= K; fout << "\n", ++i )
//            for( int j = 0; j <= K + 1; ++j )
//                fout << c[i][j] << " ";

//        for( int i = 1; i < (1 << K); fout << "\n", ++i )
//            for( int j = 1; j <= K; ++j )
//                fout << sol[i][j] << " ";

        fout << XXX;
    }

    fin.close();
    fout.close();

    return 0;
}