Cod sursa(job #2958674)

Utilizator andrei81Ragman Andrei andrei81 Data 27 decembrie 2022 18:53:09
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <bits/stdc++.h>

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[65536][20]; // dp[mask][node] = lungimea minima a unui drum care trece prin toata nodurile
// desemnate de mask(incepand nu 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] )
        {
            // cout << D[k][a.first] << " " << D[k][aux.second] + a.second << "\n";
            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;
    G.resize(n + 1);
    fin >> K;
    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 < orase.size(); i++ )
        dijsktra(i);

    for ( int i = 1; i < 65536; 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 < orase.size(); j++ )
            if ( i & (1 << j) )
                for ( int k = 0; k < 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];
}