Cod sursa(job #2569835)

Utilizator dan.cantorCantor Dan Alexandru dan.cantor Data 4 martie 2020 13:51:10
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;

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

struct Pair {
    int node, dist;
    Pair(int n, int d)
    {
        node = n;
        dist = d;
    }

    bool operator < (const Pair& p) const
    {
        return dist > p.dist;
    }
};

const int inf = 0x3f3f3f3f;

using VI = vector<int>;
using VVI = vector<VI>;
using PI = pair<int, int>;
using VVP = vector<vector<PI>>;
using VB = vector<bool>;

VVI D, din;
VVP G;
VI pr, dij;
int n, m, k;

void ReadFunction();
void Dijkstra(int x, VI& d);

int main()
{
    ReadFunction();
    Dijkstra(1, dij);
    if (k == 0)
    {
        fout << dij[n];
    }
    else
    {
        for (int i = 0; i < k; ++i)
            Dijkstra(pr[i], D[i]);

        for (int i = 0; i < k; ++i)
            din[(1 << i)][i] = dij[pr[i]];

        for(int i = 1; i < (1 << k); ++i)
            for (int j = 0; j < k; ++j)
                if(i & (1 << j))
                    for (int q = 0; q < k; ++q)
                        if (!(i & (1 << q)))
                            din[i | (1 << q)][k] = min(din[i | (1 << q)][q], din[i][j] + D[j][pr[q]]);

        int res = inf;
        for (int i = 0; i < k; ++i)
            res = min(res, din[(1<<k) - 1][i] + D[i][n]);

        fout << res;
    }
}

void ReadFunction()
{
    fin >> n >> m >> k;
    pr = VI(k + 1);
    G = VVP(n + 1);
    din = VVI((1 << k), VI(k + 1, inf));
    D = VVI(k + 1);

    for (int i = 0; i < k; ++i)
        fin >> pr[i];

    for (int i = 1, x, y, w; i <= m; ++i)
    {
        fin >> x >> y >> w;
        G[x].push_back({y, w});
        G[y].push_back({x, w});
    }
}
void Dijkstra(int x, VI& d)
{
    priority_queue <Pair> Q;
    d = VI(n + 1, inf);
    d[x] = 0;
    Q.push(Pair(x, d[x]));

    while (!Q.empty())
    {
        x = Q.top().node;
        int dist = Q.top().dist;
        Q.pop();
        if (dist > d[x])
            continue;

        for (const auto& p : G[x])
        {
            int y = p.first, w = p.second;
            if (d[y] > d[x] + w)
            {
                d[y] = d[x] + w;
                Q.push(Pair(y, d[y]));
            }
        }
    }
}