Cod sursa(job #2537447)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 3 februarie 2020 18:09:43
Problema Gather Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 760;
const int INF = 2100000000;
const int VAL = ( 1 << 16 );

int K, N, M;
int d[NMAX];
vector <int> Ad[NMAX];
vector <int> Cost[NMAX];
vector <int> Limit[NMAX];

int dp[NMAX][VAL + 2];

struct pl {
    int nod, cost, vis, nrv;

    bool operator < ( const pl & A ) const {
        return cost < A.cost;
    }
};

queue <pl> Q;

void Read()
{
    fin >> K >> N >> M;

    for( int i = 1; i <= K; ++i ) {
        int nr;
        fin >> nr;

        d[nr] = i;
    }

    int a, b, c, d;
    for( int i = 1; i <= M; ++i ) {
        fin >> a >> b >> c >> d;

        Ad[a].push_back( b );
        Cost[a].push_back( c );
        Limit[a].push_back( d );

        Ad[b].push_back( a );
        Cost[b].push_back( c );
        Limit[b].push_back( d );
    }
}

void Do()
{
    int mzg = ( 1 << ( K + 1 ));

    for( int i = 1; i <= N; ++i )
      for( int j = 0; j <= mzg; ++j )
        dp[i][j] = INF;

    dp[1][0] = 0;

    Q.push( { 1, 0, 0, 0 } );

    int u, c, vis, nr_v, w;
    while( !Q.empty() ) {
        u = Q.front().nod;
        c = Q.front().cost;
        vis = Q.front().vis;
        nr_v = Q.front().nrv;

        Q.pop();

        if( nr_v == K ) continue;

        for( int i = 0; i < Ad[u].size(); ++i ) {
            if( Limit[u][i] < nr_v ) continue;

            w = Ad[u][i];

            if( dp[w][vis] > c + ( 1 + nr_v ) * Cost[u][i] ) {
               dp[w][vis] = c + ( 1 + nr_v ) * Cost[u][i];

               Q.push( { w, c + ( 1 + nr_v ) * Cost[u][i], vis, nr_v } );
            }

            if( d[w] ) {
               if( dp[w][ ( vis | ( 1 << d[w] ) )] > c + ( nr_v + 1 ) * Cost[u][i] ) {
                  dp[w][ ( vis | ( 1 << d[w] ) )] = c + ( nr_v + 1 ) * Cost[u][i];

                  Q.push( { w, c + ( nr_v + 1 ) * Cost[u][i], vis | ( 1 << d[w] ), nr_v + 1 } );
               }
            }
        }
    }

   /* for( int i = 1; i <= N; ++i ) {
      for( int j = 0; j <= mzg; ++j )
        ( dp[i][j] < INF ) ? fout << dp[i][j] << ' ' : fout << "* ";
      fout << '\n';
    }*/

    int c_min = INF;

    for( int i = 1; i <= N; ++i )
      c_min = min( c_min, dp[i][mzg - 2] );

    fout << c_min << '\n';
}

int main()
{
    Read();
    Do();

    return 0;
}