Cod sursa(job #583797)

Utilizator ssergiussSergiu-Ioan Ungur ssergiuss Data 22 aprilie 2011 17:55:49
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.57 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 MaxN = 2005;
const int MaxK = 20;
const int MaxB = 3005;

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

struct cmp {

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

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

struct cmp2 {

    bool operator()( pair <int, int> x, pair <int, int> y ) {

        return sol[x.first][x.second] > sol[y.first][y.second];
    }
};
priority_queue < int, vector < pair <int, int> >, cmp2 > h2;

int Check( int x ) {

    int i;

    for( i = 1; i <= K; ++i )
        if( loc[i] == x )
            return i;

    return 0;
}

int main() {

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

    int i, x, y, z, nod, cnt, cbit, cbit2;
    vector < pair <int, int> > :: iterator it;

    fin >> N >> M;
    fin >> 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 ) );
    }

    if( K == 0 ) {

        memset( c, Inf, sizeof( c ) );
        c[1] = 0;
        h.push( 1 );
        f[1] = true;

        while( !h.empty() ) {

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

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

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

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

        fout << c[N];
    }
    else {

        memset( sol, Inf, sizeof( sol ) );
        cnt = Check( 1 );
        if( cnt > 0 )
            sol[1][1 << (cnt - 1)] = 0;
        else
            sol[1][0] = 0;
        h2.push( make_pair( 1, 0 ) );
        f2[1][0] = true;

        while( !h2.empty() ) {

            nod = h2.top().first;
            cbit = h2.top().second;
            h2.pop();
            f2[nod][cbit] = false;

            for( it = v[nod].begin(); it != v[nod].end(); ++it ) {

                cnt = Check( it->first );
                if( cnt > 0 ) {

                    cbit2 = cbit | (1 << (cnt - 1));
                    if( sol[nod][cbit] + it->second < sol[it->first][cbit2] ) {

                        sol[it->first][cbit2] = sol[nod][cbit] + it->second;
                        if( f2[it->first][cbit2] == false ) {

                                h2.push( make_pair( it->first, cbit2 ) );
                                f2[it->first][cbit2] = true;
                        }
                    }
                }
                else
                    if( sol[nod][cbit] + it->second < sol[it->first][cbit] ) {

                        sol[it->first][cbit] = sol[nod][cbit] + it->second;
                        if( f2[it->first][cbit] == false ) {

                            h2.push( make_pair( it->first, cbit ) );
                            f2[it->first][cbit] = true;
                        }
                    }
            }
        }

        fout << sol[N][(1 << K) - 1];
    }

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

    return 0;
}