Cod sursa(job #2958678)

Utilizator andrei81Ragman Andrei andrei81 Data 27 decembrie 2022 19:02:48
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

const int INF = (1 << 29);
int n, m, K, a, b, c, D[20][2005];
vector<int> orase;
vector<vector<pair<int, int>>> G;
int dp[131075][20];
// dp[mask][node] = lungimea minima a unui drum care trece prin toata nodurile
// desemnate de mask(incepand cu nodul 1) si ultimul nod din drum e orasul node 

void dijsktra(int k)
{
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> PQ;
    pair<int, int> aux;

    for ( int i = 1; i <= n; i++ )
        D[k][i] = INF;

    PQ.push({ 0, orase[k] });
    D[k][orase[k]] = 0;

    while ( !PQ.empty() )
    {
        aux = PQ.top();
        PQ.pop();

        for ( pair<int, int> a : G[aux.second] )
            if ( D[k][a.first] > D[k][aux.second] + a.second )
            {
                D[k][a.first] = D[k][aux.second] + a.second;
                PQ.push({ D[k][a.first], a.first });
            }
    }
}

int main()
{
    fin >> n >> m >> K;
    G.resize(n + 1);
    orase.push_back(1);

    for ( int i = 1; i <= K; i++ )
    {
        fin >> a;
        orase.push_back(a);
    }
    orase.push_back(n);

    for ( int i = 1; i <= m; i++ )
    {
        fin >> a >> b >> c;
        G[a].push_back({ b, c });
        G[b].push_back({ a, c });
    }

    for ( int i = 0; i < ( int )orase.size(); i++ )
        dijsktra(i);

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

    dp[1][0] = 0;

    for ( int i = 3; i < (1 << orase.size()); i += 2 )
        for ( int j = 1; j < ( int )orase.size(); j++ )
            if ( i & (1 << j) )
                for ( int k = 0; k < ( int )orase.size(); k++ )
                    if ( i & (1 << k) && j != k )
                        dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + D[k][orase[j]]);


    fout << dp[(1 << orase.size()) - 1][orase.size() - 1];
}