Cod sursa(job #2730844)

Utilizator beingsebiPopa Sebastian beingsebi Data 26 martie 2021 22:27:12
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4 kb
#include <bits/stdc++.h>
using namespace std;
class InParser
{
private:
    FILE *fin;
    char *buff;
    int sp;

    char read_ch()
    {
        ++sp;
        if (sp == 4096)
        {
            sp = 0;
            fread(buff, 1, 4096, fin);
        }
        return buff[sp];
    }

public:
    InParser(const char *nume)
    {
        fin = fopen(nume, "r");
        buff = new char[4096]();
        sp = 4095;
    }

    InParser &operator>>(int &n)
    {
        char c;
        while (!isdigit(c = read_ch()) && c != '-')
            ;
        int sgn = 1;
        if (c == '-')
        {
            n = 0;
            sgn = -1;
        }
        else
        {
            n = c - '0';
        }
        while (isdigit(c = read_ch()))
        {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }

    InParser &operator>>(long long &n)
    {
        char c;
        n = 0;
        while (!isdigit(c = read_ch()) && c != '-')
            ;
        long long sgn = 1;
        if (c == '-')
        {
            n = 0;
            sgn = -1;
        }
        else
        {
            n = c - '0';
        }
        while (isdigit(c = read_ch()))
        {
            n = 10 * n + c - '0';
        }
        n *= sgn;
        return *this;
    }
};
InParser f("ubuntzei.in");
ofstream g("ubuntzei.out");
// #define f cin
// #define g cout
int n, m, k, spec[22], axs[2002], dp[16][2002], dwp[20][32700];
struct nod
{
    int ind, cst;
    bool operator<(const nod &other) const
    {
        return cst > other.cst;
    }
};
struct ndd
{
    int ind, cst, sm;
    bool operator<(const ndd &other) const
    {
        return cst > other.cst;
    }
};
vector<vector<pair<int, int>>> v, w(20);
void dijkstra(int);
vector<int> aux;
int main()
{
    memset(dp, 0x3f3f3f3f, sizeof dp);
    memset(dwp, 0x3f3f3f3f, sizeof dwp);
    f >> n >> m >> k;
    v.resize(n + 1);
    axs[1] = 18;
    axs[n] = 19;
    for (int i = 1; i <= k; i++)
        f >> spec[i], axs[spec[i]] = i, aux.push_back(i);
    for (int x, y, c; m; m--)
    {
        f >> x >> y >> c;
        v[x].emplace_back(y, c);
        v[y].emplace_back(x, c);
    }
    if (k == 0)
    {
        spec[1] = 1;
        dijkstra(1);
        g << dp[1][n];
        return 0;
    }
    for (int i = 1; i <= k; i++)
    {
        dijkstra(i);
        for (int j = 1; j < i; j++)
            w[i].emplace_back(j, dp[i][spec[j]]),
                w[j].emplace_back(i, dp[i][spec[j]]);
        w[i].emplace_back(0, dp[i][1]);
        w[0].emplace_back(i, dp[i][1]);
        w[i].emplace_back(k + 1, dp[i][n]);
        w[k + 1].emplace_back(i, dp[i][n]);
    }
    priority_queue<ndd> pq;
    dwp[0][0] = 0;
    pq.push({0, 0, 0});
    while (!pq.empty())
    {
        ndd ac = pq.top();
        pq.pop();
        if (dwp[ac.ind][ac.sm] < ac.cst)
            continue;
        if (ac.ind == k + 1 && ac.sm + 1 == (1 << k))
        {
            g << ac.cst;
            return 0;
        }
        for (const auto &i : w[ac.ind])
        {
            int nsm = ac.sm;
            if (i.first != k + 1 && i.first)
                nsm |= (1 << (i.first - 1));
            if (dwp[i.first][nsm] > ac.cst + i.second)
                dwp[i.first][nsm] = ac.cst + i.second, pq.push({i.first, ac.cst + i.second, nsm});
        }
    }
    return 0;
}
void dijkstra(int x)
{
    priority_queue<nod> pq;
    vector<bool> bif(20);
    int ndd = k + 2;
    dp[x][spec[x]] = 0;
    pq.push({spec[x], 0});
    while (!pq.empty() && ndd)
    {
        nod ac = pq.top();
        pq.pop();
        if (dp[x][ac.ind] < ac.cst)
            continue;
        if (axs[ac.ind] && !bif[axs[ac.ind]])
            bif[axs[ac.ind]] = 1, ndd--;
        for (const auto &i : v[ac.ind])
            if (dp[x][i.first] > ac.cst + i.second)
                dp[x][i.first] = ac.cst + i.second,
                pq.push({i.first, dp[x][i.first]});
    }
}