Cod sursa(job #2823344)

Utilizator Iordache_CezarIordache Cezar Iordache_Cezar Data 28 decembrie 2021 09:33:37
Problema Ubuntzei Scor 95
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <bits/stdc++.h>
#define NMAX 2004
#define INF 1000000000

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

int n, m, k, cnt, prieteni[20], dp[20][NMAX], tr[135000][20];
int muchii[NMAX][NMAX];
set < pair <int, int> > S;

void citire();
void Dijkstra(int p);
void path();

int main()
{
    citire();
    for (int i = 1; i <= k + 1; i++)
        Dijkstra(prieteni[i]);
    path();
    return 0;
}

void citire()
{
    fin >> n >> m;
    fin >> k;
    for (int i = 1; i <= k; i++)
        fin >> prieteni[i];
    prieteni[k+1] = 1;
    for (int i = 1; i <= m; i++)
    {
        int x, y, c;
        fin >> x >> y >> c;
        muchii[x][y] = c;
        muchii[y][x] = c;
    }
}

void Dijkstra(int p)
{
    cnt++;
    for (int i = 1; i <= n; i++)
        dp[cnt][i] = INF;
    dp[cnt][p] = 0;
    S.insert({0, p});

    while (!S.empty())
    {
        int nod = S.begin()->second;
        S.erase(S.begin());

        for (int vecin = 1; vecin <= n; vecin++)
            if (muchii[nod][vecin])
            {

                int cost = muchii[nod][vecin];
                if (dp[cnt][vecin] > dp[cnt][nod] + cost)
                {
                    dp[cnt][vecin] = dp[cnt][nod] + cost;
                    S.insert({dp[cnt][vecin], vecin});
                }
            }
    }
}

void path()
{
    if (k == 0)
    {
        fout << dp[1][n];
        return;
    }
    for (int j = 0; j < k; j++)
        tr[(1 << k) ^ (1 << j)][j] = dp[k+1][prieteni[j+1]];
    int maxim = (1 << k+1);
    for (int mask = (1 << k) + 1; mask < maxim; mask++)
    {
        for (int j = 0; j < k; j++)
        {
            int bit = 1 << j;
            if (bit & mask)
            {
                int bit2;
                for (int j2 = 0; j2 < k; j2++)
                {
                    bit2 = 1 << j2;
                    if ((bit2 & mask) == 0)
                    {
                        if (tr[mask ^ bit2][j2] > tr[mask][j] + dp[j+1][prieteni[j2+1]] || tr[mask ^ bit2][j2] == 0)
                            tr[mask ^ bit2][j2] = tr[mask][j] + dp[j+1][prieteni[j2+1]];
                    }
                }
            }
        }
    }

    int mask = maxim - 1;
    int minim = INF;
    for (int j = 0; j < k; j++)
        minim = min(minim, tr[mask][j] + dp[j+1][n]);
    fout << minim;
}