Cod sursa(job #2703270)

Utilizator SergiuS3003Sergiu Stancu Nicolae SergiuS3003 Data 7 februarie 2021 21:43:29
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define pb push_back
#define pii pair<int,int>
#define mp make_pair
using namespace std;
ifstream f ( "ubuntzei.in" );
ofstream g ( "ubuntzei.out" );
const int NMAX = 2001, INF = 2e9;
int N, M, K;
vector<pii>G[NMAX];
vector<int>GT[NMAX];
int friends[17], index;
int d[17][NMAX], cost[17][17];
bool InQueue[NMAX];
struct Comp
{
    bool operator () ( const int a, const int b ) const
    {
        return d[index][a] > d[index][b];
    }
};
priority_queue<int, vector<int>, Comp>Q;
int dp[1 << 17][17];
void Djikstra()
{
    int x0 = friends[index];

    for ( int j = 1; j <= N; j++ )
        d[index][j] = INF;

    d[index][x0] = 0;
    Q.push ( x0 );

    while ( !Q.empty() )
    {
        int vfmin = Q.top();
        Q.pop();
        InQueue[vfmin]=0;
        for ( auto i : G[vfmin] )
        {
            int dist = d[index][vfmin] + i.second;
            int ymin = i.first;

            if ( d[index][ymin] > dist )
            {
                d[index][ymin] = dist;

                if ( !InQueue[ymin] )
                {
                    InQueue[ymin] = 1;
                    Q.push ( ymin );
                }
            }
        }
    }
}
int main()
{
    f >> N >> M >> K;

    for ( int i = 1; i <= K; i++ )
        f >> friends[i];

    friends[0] = 1;
    friends[K + 1] = N;

    for ( int i = 1; i <= M; i++ )
    {
        int x, y, c;
        f >> x >> y >> c;
        G[x].pb ( mp ( y, c ) );
        G[y].pb ( mp ( x, c ) );
    }

    for ( int i = 0; i <= K + 1; i++ )
    {
        index = i;
        Djikstra();

        for ( int j = 0; j <= K + 1; j++ )
            cost[i][j] = d[i][friends[j]];
    }

    if ( K == 0 )
    {
        g << cost[0][1];
        return 0;
    }

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

    for ( int j = 1; j <= K; j++ )
        dp[ ( 1 << j ) + 1][j] = cost[0][j];

    for ( int i = 1; i < 1 << ( K + 1 ); i++ )
        for ( int j = 0; j <= K; j++ )
            if ( i & ( 1 << j ) )
                for ( int k = 1; k <= K; k++ )
                    dp[i][j] = min ( dp[i][j], dp[i ^ ( 1 << j )][k] + cost[k][j] );

    int ans = INF;

    for ( int i = 1; i <= K; i++ )
        ans = min ( ans, dp[ ( 1 << ( K + 1 ) ) - 1][i] + cost[i][K + 1] );

    g << ans;
    return 0;
}