Cod sursa(job #1356233)

Utilizator pop_bogdanBogdan Pop pop_bogdan Data 23 februarie 2015 12:02:26
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <fstream>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;

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

priority_queue < pair<int,int> , vector<pair<int,int> > , greater<pair<int,int> > > P;
vector <pair<int,int > > G[2001];

int N, M, K, x, y ,z;
int L[18], D[2001], DP[(1<<18)][18], DK[18][18];

void Dijkstra(int source);

int main()
{
    is >> N >> M >> K;

    L[0] = 1;
    for ( int i = 1; i <= K; ++i )
        is >> L[i];
    L[K+1] = N;
    K = K+2;
    for ( int i = 1; i <= M; ++i )
    {
        is >> x >> y >> z;
        G[x].push_back(make_pair(y,z));
        G[y].push_back(make_pair(x,z));
    }

    for ( int i = 0; i < K; ++i )
    {
        Dijkstra(L[i]);
        for ( int j = 0; j < K; ++j )
            DK[i][j] = D[L[j]];
        DK[i][i] = 0;
    }

    memset(DP,0x3f3f3f3f,sizeof(DP));
    DP[1][0] = 0;

    int allnodes = (1<<(K));
    for ( int i = 1; i < allnodes; ++i ) // toate submultimile de noduri accesate
        for ( int j = 0; j < K; ++j ) // nodul in care suntem
            if ( i & (1<<j) )
            for ( int  k = 0; k < K; ++k ) // nodul din care venim
                if(i & (1 << k))
                    DP[i][j] = min(DP[i ^ (1<<j)][k] + DK[k][j], DP[i][j] );


    os << DP[allnodes-1][K-1];


    is.close();
    os.close();
}

void Dijkstra(int source)
{
    for ( int i = 1; i <= N; ++i )
        D[i] = 0x3f3f3f3f3f;
    D[source] = 0;
    P.push(make_pair(0,source));
    int node;

    while ( !P.empty() )
    {
        node = P.top().second;
        P.pop();

        for ( vector <pair<int,int> > :: iterator it = G[node].begin(); it != G[node].end(); ++it )
        {
            if ( D[node] + it->second < D[it->first] )
            {
                D[it->first] = D[node] + it->second;
                P.push(make_pair(D[it->first],it->first));
            }
        }
    }
}