Cod sursa(job #2911726)

Utilizator raulandreipopRaul-Andrei Pop raulandreipop Data 1 iulie 2022 16:49:08
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <vector>
#include <queue>

using namespace std;
typedef long long ll;

struct drum {
    int to; ll cost;
};

ll dist[2002][2002];
int t[20];
vector<drum> adj[2002];
ll dp[(1 << 16)][16][16];

void dijsktra (int nod)
{
    queue<drum> q;
    q.push({nod, 0});
    while (!q.empty())
    {
        drum crt = q.front();
        q.pop();
        if (crt.cost > dist[nod][crt.to]) continue;
        for (auto to : adj[crt.to])
        {
            if (dist[nod][crt.to] + to.cost < dist[nod][to.to])
            {
                dist[nod][to.to] = dist[nod][crt.to] + to.cost;
                dist[to.to][nod] = dist[nod][to.to];
                q.push({to.to, dist[to.to][nod]});
            }
        }
    }
}

int main ()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.in", "w", stdout);
    int n, m; cin >> n >> m;
    int k; cin >> k;
    for (int i = 0; i < k; i++)
    {
        cin >> t[i];
    }
    for (int i = 1; i <= m; i++)
    {
        int x, y; ll c;
        cin >> x >> y >> c;
        adj[x].push_back({y, c});
        adj[y].push_back({x, c});
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            dist[i][j] = 1e9;
            if (i == j) dist[i][j] = 0;
        }
    }
    for (int i = 0; i < k; i++)
    {
        dijsktra(t[i]);
    }
    t[k] = n;
    
    for (int i = 0; i < (1 << 16); i++)
    {
        for (int j = 0; j <= k; j++)
        {
            for (int t = 0; t <= k; t++)
                dp[i][j][t] = 1e18;
        }
    }
    for (int i = 0; i < k; i++)
    {
        dp[(1 << i)][i][1] = dist[1][t[i]];
    }
    for (int l = 1; l < k; l++)
    {
        for (int i = 0; i < k; i++)
        {
            for (int mask = 0; mask < (1 << k); mask++)
            {
                if ((mask & (1 << i)) == 0) continue;
                for (int j = 0; j < k; j++)
                {
                    if ((mask & (1 << j)) != 0) continue;
                    dp[mask + (1 << j)][j][l + 1] =
                    min(dp[mask + (1 << j)][j][l + 1],
                    dp[mask][i][l] + dist[t[i]][t[j]]);
                }
            }
        }
    }
    ll ans = 1e18;
    for (int i = 0; i < k; i++)
    {
        ans = min (ans, dp[(1 << k) - 1][i][k] + dist[t[i]][n]);
    }
    cout << ans <<'\n';
}