Cod sursa(job #2926334)

Utilizator IvanAndreiIvan Andrei IvanAndrei Data 17 octombrie 2022 18:15:12
Problema Ubuntzei Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <fstream>
#include <queue>
#include <vector>
#include <bitset>

using namespace std;

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

#define pii pair <int, int>

///first pt nod, second cost
///in vect pt muchii, first repr ce se adauga la conf noua

struct str{
    int mask, lst, cost;
    bool operator < (const str &x) const
    {
        return cost > x.cost;
    }
};

const int max_size = 2e3 + 1, max_c = 20, INF = 2e9 + 1;

int d[(1 << max_c)], c[max_c], di[max_c], df[max_c], n, k;
vector <pii> gv[max_size], mc[max_c];
bitset <(1 << max_c)> viz;
priority_queue <pii> pq;
priority_queue <str> pq2;

void djk1 (int nod)
{
    for (int i = 1; i <= n; i++)
    {
        viz[i] = 0;
        d[i] = INF;
    }
    d[nod] = 0;
    pq.push({nod, 0});
    while (!pq.empty())
    {
        pii nnod = pq.top();
        pq.pop();
        if (viz[nnod.first])
            continue;
        viz[nnod.first] = 1;
        for (auto f : gv[nnod.first])
        {
            if (d[nnod.first] + f.second < d[f.first])
            {
                d[f.first] = d[nnod.first] + f.second;
                pq.push({f.first, d[f.first]});
            }
        }
    }
}

void djk2 (int c)
{
    for (int i = 0; i < (1 << k); i++)
    {
        d[i] = INF;
        viz[i] = 0;
    }
    d[(1 << c)] = di[c];
    pq2.push({1 << c, c, 0});
    while (!pq2.empty())
    {
        str x = pq2.top();
        pq2.pop();
        if (viz[x.mask] == 1)
            continue;
        viz[x.mask] = 1;
        for (auto f : mc[x.lst])
        {
            int newmask = (x.mask | (1 << f.first));
            if (newmask == (1 << k) - 1)
            {
                d[(1 << k) - 1] = min(d[x.mask] + f.second + df[f.first], d[(1 << k) - 1]);
            }
            else
            {
                if (d[x.mask] + f.second < d[newmask])
                {
                    d[newmask] = d[x.mask] + f.second;
                    pq2.push({newmask, f.first, d[newmask]});
                }
            }
        }
    }
}

int main ()
{
    int m;
    in >> n >> m >> k;
    for (int i = 1; i <= k; i++)
    {
        in >> c[i];
    }
    while (m--)
    {
        int x, y, z;
        in >> x >> y >> z;
        gv[x].push_back({y, z});
        gv[y].push_back({x, z});
    }
    if (k == 0)
    {
        djk1(1);
        out << d[n];
        in.close();
        out.close();
        return 0;
    }
    if (k == 1)
    {
        djk1(c[1]);
        out << d[1] + d[n];
        in.close();
        out.close();
        return 0;
    }
    for (int i = 1; i <= k; i++)
    {
        djk1(c[i]);
        di[i] = d[n];
        for (int j = 1; j <= k; j++)
        {
            if (i == j)
                continue;
            out << d[c[j]] << " ";
            mc[i].push_back({j, d[c[j]]});
            mc[j].push_back({i, d[c[i]]});
        }
    }
    int ans = INF;
    for (int i = 1; i <= k; i++)
    {
        djk2(i);
        ans = min(ans, d[(1 << k) - 1]);
    }
    out << ans;
    in.close();
    out.close();
    return 0;
}