Cod sursa(job #2990365)

Utilizator Luka77Anastase Luca George Luka77 Data 7 martie 2023 20:21:00
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.45 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, ans = INT_MAX;
bool frq[NMAX];
long long adj[NMAX][NMAX], dp[BIT][25];
long long loca[NMAX], arr[NMAX];
vector<muchie>g[NMAX];

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

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

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

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

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

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

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

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

    for(int i = 0; i < BIT; ++ i)
    {
        for(int j = 0; j < 25; ++ 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[loca[i]][loca[j]]);
                }
            }
        }
    }

    /*for(int mask = 1; mask <= (1 << k + 1) - 1; ++ mask)
    {
        for(int i = 0; i <= k; ++ i)
        {
            cout << dp[mask][i] << ' ';
        }
        cout << '\n';
    }*/

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