Cod sursa(job #2990379)

Utilizator Luka77Anastase Luca George Luka77 Data 7 martie 2023 20:30:34
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <bits/stdc++.h>
using namespace std;

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

struct muchie
{
    int node, cost;
};

struct heap
{
    int node, cost;
    bool operator < (const heap &num) const
    {
        return cost > num.cost;
    }
};

const int NMAX = 2005, INF = 1e9, BIT = (1 << 15 ) + 5;
int n, m, k;
int adj[20][NMAX], dp[BIT][19];
int loca[NMAX], arr[NMAX];
vector<muchie>g[NMAX];

inline void dijkstra(int start, int poz)
{
    int dist[NMAX];
    priority_queue<heap>pq;
    pq.push({start, 0});
    adj[poz][start] = 0;

    while(!pq.empty())
    {
        int curr_node = pq.top().node;
        pq.pop();

        for(auto new_node : g[curr_node])
        {
            if(adj[poz][new_node.node] > adj[poz][curr_node] + new_node.cost)
            {
                adj[poz][new_node.node] = adj[poz][curr_node] + new_node.cost;
                pq.push({new_node.node, adj[poz][new_node.node]});
            }
        }
    }
}

int main()
{
    cin >> n >> m >> k;

    for(int i = 1; i <= k; ++ i)
        cin >> loca[i];
    loca[0] = 1;
    loca[++k] = n;

    for(int i = 1; i <= m; ++ i)
    {
        int x, y, cost;
        cin >> x >> y >> cost;
        g[x].push_back({y, cost});
        g[y].push_back({x, cost});
    }

    for(int i = 0; i < 20; ++ i)
        for(int j = 0; j < NMAX; ++ j)
            adj[i][j] = INF;

    for(int i = 1; i <= k; ++ i)
    {
        dijkstra(loca[i], i);
    }

    for(int i = 0; i < BIT; ++ i)
    {
        for(int j = 0; j < 18; ++ j)
            dp[i][j] = INF;
    }

    for(int i = 0; i <= k; ++ i)
        dp[0][i] = 0;
    dp[1][0] = 0;

    // dp(mask)(i) minimul cost de a ajunge de la 1 la nodul special i a.i. sa satisfacem masca

    for(int mask = 1; mask <= (1 << (k + 1)) - 1; ++ mask)
    {
        for(int i = 0; i <= k; ++ i)
        {
            if(mask & (1 << i))
            {
                for(int j = 0; j <= k; ++ j)
                {
                    dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + adj[i][loca[j]]);
                }
            }
        }
    }

    fout << dp[(1 << (k +1)) - 1][k] << '\n';
}