Cod sursa(job #3285491)

Utilizator ALEXANDRUspargoaseAlexandru Joita ALEXANDRUspargoase Data 13 martie 2025 00:44:32
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <fstream>
#include <vector>
#include <queue>
#include <fstream>
using namespace std;

typedef pair<int, int> pii;
const int Kmax = 15, Nmax = 2e3, inf = 1e9;

// dp[i][mask] = best cost to get to special point i that is in configuration mask
//  size is k * 2^k (0 <= i < k)
vector<vector<pii>> g;
vector<vector<int>> dp, dist;

void dijkstra(int start, vector<int> &dist)
{
    priority_queue<pii, vector<pii>, greater<pii>> q;
    dist[start] = 0;
    q.push({0, start});

    while (!q.empty())
    {
        int cost = q.top().first, nod = q.top().second;
        q.pop();

        if (cost != dist[nod]) // vizited node
            continue;

        for (pii i : g[nod])
            if (dist[i.first] > cost + i.second)
            {
                dist[i.first] = cost + i.second;
                q.push({dist[i.first], i.first});
            }
    }
}

int main()
{
    ifstream cin("ubuntzei.in");
    ofstream cout("ubuntzei.out");

    int n, m, k;
    cin >> n >> m >> k;
    g.resize(n + 1);
    dp.resize(k, vector<int>(1 << k, inf));
    dist.resize(k, vector<int>(n + 1, inf));

    vector<int> c(k);
    for (int i = 0; i < k; i++)
        cin >> c[i];
    for (int i = 0; i < m; i++)
    {
        int x, y, c;
        cin >> x >> y >> c;
        g[x].push_back({y, c});
        g[y].push_back({x, c});
    }

    if (k == 0)
    {
        vector<int> distances(n + 1, inf);
        dijkstra(1, distances);
        cout << distances[n];
        return 0;
    }

    for (int i = 0; i < k; i++)
        dijkstra(c[i], dist[i]);

    for (int mask = 1; mask < (1 << k); mask++)
        for (int i = 0; i < k; i++)
        {
            if (!(mask & (1 << (i))))
                continue;

            if (mask == (1 << i)) // ubuntzel
                dp[i][mask] = dist[i][1];
            else
                for (int j = 0; j < k; j++)
                    if (i != j && mask & (1 << j))
                        dp[i][mask] = min(dp[i][mask], dp[j][mask ^ (1 << i)] + dist[j][c[i]]);
        }

    int best = inf;
    for (int i = 0; i < k; i++)
        best = min(best, dp[i].back() + dist[i][n]);
    cout << best;

    return 0;
}