Cod sursa(job #2970713)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 25 ianuarie 2023 19:29:31
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;

using namespace std;

const int NMAX = 2005;
const int BITT = 15;
const int PUT_MAX = (1 << BITT) + 5;
/*******************************/
// INPUT / OUTPUT

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
/*******************************/
/// GLOBAL DECLARATIONS

int N, M, K;
int ans;
bool vis[NMAX];
int localitate_bit[BITT];
int dp[BITT][PUT_MAX], d[BITT][NMAX];

struct Node
{
    int node, cost;

    const bool operator < (const Node &other) const {
        return cost > other.cost;
    }
};

vector <Node> adj[NMAX];
/*******************************/
/// FUNCTIONS

void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
    f >> N >> M >> K;

    for (int i = 0 ; i < K ; ++ i)
        f >> localitate_bit[i];

    int a, b, c;
    for (int i = 0 ; i < M ; ++ i)
    {
        f >> a >> b >> c;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c});
    }
}
///-------------------------------------
void dijkstra(ci &bit, ci &start_node)
{
    memset(vis, 0, sizeof(vis));
    priority_queue <Node> pq;
    pq.push({start_node, 0});

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

        if (!vis[node])
        {
            vis[node] = true;
            d[bit][node] = cost;

            for (auto u: adj[node])
            {
                if (!vis[u.node])
                    pq.push({u.node, cost + u.cost});
            }
        }
    }
}
///-------------------------------------
inline void Solution()
{
    if (K == 0)
    {
        dijkstra(0, 1);
        ans = d[0][N];
        return;
    }

    for (int i = 0 ; i < K ; ++ i)
        dijkstra(i, localitate_bit[i]);
    
    int bit_unic, best;
    for (int mask = 1 ; mask < (1 << K) ; ++ mask)
    {
        if (__builtin_popcount(mask) == 1)
        {
            bit_unic = int(log2(mask));
            dp[bit_unic][mask] = d[bit_unic][1];
            continue;
        }

        for (int i = 0 ; i < K ; ++ i)
        {
            if (!(mask & (1 << i))) continue;
            best = INT32_MAX;
            for (int j = 0 ; j < K ; ++ j)
            {
                if (i == j || !(mask & (1 << j))) continue;
                // g << (mask ^ (1 << i)) << "\n";
                // g << i << " " << j << " " << dp[j][(mask ^ (1 << i))] << " " << d[i][localitate_bit[j]] << "\n";
                best = min(best, dp[j][mask ^ (1 << i)] + d[i][localitate_bit[j]]);
            }
            dp[i][mask] = best;
        }
    }

    ans = INT32_MAX;
    for (int i = 0 ; i < K ; ++ i)
    {
        // g << dp[i][(1 << K) - 1] << " " << d[i][N] << "\n";
        ans = min(ans, dp[i][(1 << K) - 1] + d[i][N]);
    }
}
///-------------------------------------
inline void Output()
{
    g << ans;
}
///-------------------------------------
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    ReadInput();
    Solution();
    Output();
    return 0;
}