Cod sursa(job #2610259)

Utilizator calinfloreaCalin Florea calinflorea Data 4 mai 2020 17:46:29
Problema Ubuntzei Scor 0
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <bits/stdc++.h>
#include "E:\C++\Ubuntzei\heap.h"
#define oo (1 << 30)

using namespace std;

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

int a[DimMax], drum[DimMax], dist[17][17];
vector <pair <int, int> > L[DimMax];
Pereche Q[DimMax];
Atom P;
int n, m, K;
int dp[17][1 << 17];

void Citire ()
{
    int x, y, c;
    fin >> n >> m >> K;

    for (int i = 1; i <= K; i++)
        fin >> a[i];
    a[0] = 1;
    K++;
    a[K] = n;
    for (int i = 1; i <= m; i++)
    {
        fin >> x >> y >> c;

        L[x].push_back ({y, c});
        L[y].push_back ({x, c});
    }
}

void Dijkstra (int M)
{
    int i, cost, nod;

    Insert(Q, P, {0, M});
    for (int i = 1; i <= n; i++)
        drum[i] = oo;
    drum[M] = 0;

    while (P)
    {
        i = Remove(Q, P);
        for (int j = 0; j < L[i].size(); j++)
        {
            nod = L[i][j].first;
            cost = L[i][j].second;

            if (drum[nod] > drum[i] + cost)
            {
                drum[nod] = drum[i] + cost;
                Insert (Q, P, {drum[nod], nod});
            }
        }
    }
}

void Construieste ()
{
    for (int i = 0; i <= K; i++)
    {
        Dijkstra(a[i]);

        for (int j = 0; j <= K; j++)
            dist[i][j] = drum[a[j]];
    }
}

void Initialiazare ()
{
    for (int i = 0; i <= K; i++)
        for (int j = 1; j <= (1 << K) - 1; j++)
            dp[i][j] = oo;

    for(int i = 0; i <= K; i++)
        for(int j = 0; j <= K; j++)
            dist[i][j] = oo;
}

void Dinamica ()
{
    dp[0][1] = 0;
    int ans = oo;

    for (int i = 1; i <= (1 << K) - 1; i++)
        for (int j = 0; j <= K; j++)
            if ((i & (1 << j)) != 0)
                for (int p = 0; p <= K; p++)
                    if ((i & (1 << p)) == 0)
                        dp[p][i | (1 << p)] = min (dp[p][i | (1 << p)],
                                                  dp[j][i] + dist[j][p]);


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

    fout << ans << "\n";
}

int main()
{
    Citire();
    Initialiazare();
    Construieste();
    Dinamica();

    return 0;
}