Cod sursa(job #2775747)

Utilizator pielevladutPiele Vladut Stefan pielevladut Data 16 septembrie 2021 22:36:08
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <bits/stdc++.h>

using namespace std;

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

int n, m, k;
int distante[2020][2020];
int v[20];
int dp[33033][20];
struct elem
{
    int nod, cost;
    bool operator < (const elem other) const
    {
        return cost > other.cost;
    }
};
vector<elem> g[2020];
priority_queue<elem> coada;

void Dijkstra(int sursa)
{
    distante[sursa][sursa] = 0;
    coada.push({sursa, 0});
    while(!coada.empty())
    {
        int nod = coada.top().nod;
        int cost = coada.top().cost;
        coada.pop();
        if(distante[sursa][nod] != cost)
            continue;
        for(auto it : g[nod])
        {
            if(cost + it.cost < distante[sursa][it.nod])
            {
                distante[sursa][it.nod] = cost + it.cost;
                coada.push({it.nod, cost + it.cost});
            }
        }
    }
}

int main()
{
    fin >> n >> m >> k;
    for(int i = 0; i < k; i ++)
    {
        fin >> v[i];
    }
    while(m--)
    {
        int a, b, c;
        fin >> a >> b >> c;
        g[a].push_back({b, c});
        g[b].push_back({a, c});
    }
    for(int i = 0; i <= n; i ++)
    {
        for(int j = 0; j <= n; j ++)
            distante[i][j] = INT_MAX;
    }
    for(int i = 0; i <= (1 << k); i ++)
    {
        for(int j = 0; j <= k; j ++)
        {
            dp[i][j] = INT_MAX;
        }
    }
    Dijkstra(1);
    if(k == 0)
    {
        fout << distante[1][n] << '\n';
        return 0;
    }
    for(int i = 0; i < k; i ++)
    {
        Dijkstra(v[i]);
    }
    for(int i = 0; i < k; i ++)
    {
        dp[(1 << i)][i] = distante[1][v[i]];
    }
    for(int mask = 1; mask < (1 << k); mask ++)
    {
        for(int i = 0; i < k; i ++)
        {
            if(mask & (1 << i))
            {
                for(int j = 0; j < k; j ++)
                {
                    if(j != i && (mask & (1 << j)))
                    {
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + distante[v[i]][v[j]]);
                    }
                }
            }
        }
    }
    int ans = INT_MAX;
    for(int i = 0; i < k; i ++)
    {
        ans = min(ans, dp[(1 << k) - 1][i] + distante[v[i]][n]);
    }
    fout << ans << '\n';
}