Cod sursa(job #3206165)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 21 februarie 2024 19:13:13
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <bits/stdc++.h>

using namespace std;

const long long max_size = 2e3 + 20, max_c = (1 << 15) + 20, INF = 2e9 + 1;

struct str{
    long long nod, val;
    bool operator < (const str & aux) const
    {
        return val > aux.val;
    }
};

long long spec[20], cost[20][20], dp[max_c][20], d[max_size], n;
/// cost x - k = cost x - n
vector <pair <long long, long long>> mc[max_size];
priority_queue <str> pq;

void djk (long long nod)
{
    for (long long i = 1; i <= n; i++)
    {
        d[i] = INF;
    }
    d[nod] = 0;
    pq.push({nod, 0});
    while (!pq.empty())
    {
        nod = pq.top().nod;
        long long val = pq.top().val;
        pq.pop();
        if (val > d[nod])
        {
            continue;
        }
        for (auto f : mc[nod])
        {
            if (d[nod] + f.second < d[f.first])
            {
                d[f.first] = d[nod] + f.second;
                pq.push({f.first, d[f.first]});
            }
        }
    }
}

void solve ()
{
    long long m, k;
    cin >> n >> m >> k;
    for (long long i = 0; i < k; i++)
    {
        cin >> spec[i];
    }
    while (m--)
    {
        long long x, y, z;
        cin >> x >> y >> z;
        mc[x].push_back({y, z});
        mc[y].push_back({x, z});
    }
    for (long long i = 1; i < (1 << k); i++)
    {
        for (long long j = 0; j < k; j++)
        {
            dp[i][j] = INF;
        }
    }
    for (long long i = 0; i < k; i++)
    {
        djk(spec[i]);
        for (long long j = 0; j < k; j++)
        {
            cost[i][j] = d[spec[j]];
        }
        cost[i][k] = d[n];
        dp[(1 << i)][i] = d[1];
    }
    for (long long i = 1; i < (1 << k); i++)
    {
        for (long long j = 0; j < k; j++)
        {
            if ((i & (1 << j)) != 0)
            {
                for (long long t = 0; t < k; t++)
                {
                    if ((i & (1 << t)) == 0)
                    {
                        dp[i | (1 << t)][t] = min(dp[i | (1 << t)][t], dp[i][j] + cost[j][t]);
                    }
                }
            }
        }
    }
    long long ans = INF, full = (1 << k) - 1;
    for (long long i = 0; i < k; i++)
    {
        ans = min(ans, dp[full][i] + cost[i][k]);
    }
    if (k == 0)
    {
        djk(1);
        cout << d[n];
        return;
    }
    cout << ans;
    cout << '\n';
}

signed main ()
{
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#else
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
#endif // LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    long long t;
    //cin >> t;
    t = 1;
    while (t--)
    {
        solve();
    }
    return 0;
}