Cod sursa(job #877808)

Utilizator Coman95coman cosmin Coman95 Data 13 februarie 2013 11:21:44
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.53 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

#define PII pair<int, int>
#define INF 0x3f3f3f3f
#define mp make_pair
#define pb push_back
typedef vector<PII>::iterator IT;

int n, m, nk, nr;
queue<int> T;
vector<PII> G[2001];
int k[20];
int dd[20][20];
int bst[1<<16][16];

void Dijkstra( int nod );

int main()
{
    int x , y, c;
    fin >> n >> m >> nk;
    for( int i = 1; i <= nk; ++i )
        fin >> k[i];
    k[0] = 1;
    k[nk+1] = n;
    nk++;
    for( int i = 1; i <= m; ++i )
    {
        fin >> x >> y >> c;
        G[x].pb(mp(c, y));
        G[y].pb(mp(c, x));
    }
    for( int i = 0; i <= nk; ++i )
        for( int j = 0; j <= nk ; ++j )
            dd[i][j] = INF;
    for( int i = 0; i < nk; ++i )
        Dijkstra( k[i] );
    /*
    for( int i = 0; i < nk; ++i )
    {
        for( int j = 0; j <= nk; ++j )
            fout << dd[i][j] << ' ';
        fout << '\n';
    }*/
    for( int i = 1; i <= nk; ++i)
        bst[1<<(i-1)][i-1] = dd[0][i];
    for( int i = 1; i < (1<<nk); ++i)
        for( int j = 0; j < nk;++j)
            if( i & (1<<j) )
                for( int k = 0; k < nk; ++k)
                    if( !(i & (1<<k) ))
                    {
                        if( bst[i | (1<<k)][k] == 0)
                            bst[i | (1<<k)][k] = bst[i][j] + dd[j+1][k+1];
                        else
                            bst[i | (1<<k)][k] = min(bst[i | (1<<k)][k], bst[i][j] + dd[j+1][k+1]);
                    }
    int i = (1<<nk) - 1;
    int sol;
    for(int j = 0; j < nk; ++j)
        sol = min( sol, bst[i][j] + dd[j+1][nk+1] );

    if( nk == 0 )
        fout << dd[0][1];
    else if (nk == 1)
        fout << dd[0][1] + dd[1][2];
    else
        fout<<sol;
    fin.close();
    fout.close();
    return 0;
}

void Dijkstra( int nod )
{
    vector<int> d;
    int x;
    d.assign( n + 1, INF );
    d[nod] = 0;
    T.push( nod );
    while( !T.empty() )
    {
        x = T.front();
        T.pop();
        for( IT it = G[x].begin(); it != G[x].end(); ++it )
        {
            if( d[it->second] > d[x] + it->first )
            {
                d[it->second] = d[x] + it->first;
                T.push( it->second );
            }
        }
    }
    /*for( int i = 1; i < d.size(); ++i )
        fout << d[i] << ' ';
    fout << '\n';*/
    dd[nr][0] = 0;
    for( int i = 1; i <= nk; ++i )
        dd[nr][i] = d[k[i]];
    nr++;
}