Cod sursa(job #2640802)

Utilizator alex_braslasuBraslasu Alexandru alex_braslasu Data 8 august 2020 12:48:40
Problema Ubuntzei Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.73 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

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

const int INF = 1000000000;
int n, m, k, x, y, z, i, j, top_heap = 0, mask, mini, v[18], dis[18][2020], heap[10020], d[17][(1 << 17) + 10];
bool ok[2020];
vector<pair<int, int > > t[2020];
vector<pair<int, int > >::iterator it;
pair<int, int > p;

int MINIM(int a, int b)
{
    if (a <= b)
        return a;
    return b;
}

void UpHeap(int nod)
{
    int tata = nod / 2;
    if (tata && heap[tata] > heap[nod])
    {
        swap(heap[tata], heap[nod]);
        UpHeap(tata);
    }
}

void DownHeap(int nod)
{
    int fiu = 2 * nod;
    if (fiu <= top_heap && fiu + 1 <= top_heap && heap[fiu + 1] < heap[fiu])
        ++fiu;
    if (fiu <= top_heap && heap[nod] > heap[fiu])
    {
        swap(heap[nod], heap[fiu]);
        DownHeap(fiu);
    }
}

void Insert(int nod)
{
    heap[++top_heap] = nod;
    UpHeap(top_heap);
}

void Sterge(int nod)
{
    swap(heap[nod], heap[top_heap]);
    --top_heap;
    DownHeap(nod);
}

void Dijkstra(int nodst)
{
    dis[nodst][nodst] = 0;
    Insert(nodst);
    ok[nodst] = true;
    while (top_heap)
    {
        int nodc = heap[1];
        ok[nodc] = false;
        Sterge(1);
        for (it = t[nodc].begin(); it < t[nodc].end(); ++it)
        {
            p = *it;
            int vecin = p.second;
            int cost = p.first;
            if (dis[nodst][nodc] + cost < dis[nodst][vecin])
            {
                dis[nodst][vecin] = dis[nodst][nodc] + cost;
                if (!ok[vecin])
                {
                    ok[vecin] = true;
                    Insert(vecin);
                }
            }
        }
    }
}

int main()
{
    f >> n >> m >> k;
    for (i = 1; i <= k; ++i)
        f >> v[i];
    for (i = 1; i <= m; ++i)
    {
        f >> x >> y >> z;
        t[x].push_back({z, y});
        t[y].push_back({z, x});
    }
    v[0] = 1; v[++k] = n;
    for (i = 0; i <= k; ++i)
        for (j = 1; j <= n; ++j)
            dis[v[i]][j] = INF;
    for (i = 0; i <= k; ++i)
        Dijkstra(v[i]);
    for (i = 0; i <= k; ++i)
        for (j = 1; j <= (1 << k); ++j)
            d[i][j] = INF;
    d[0][1] = 0;
    for (mask = 1; mask < (1 << k); ++mask)
        for (i = 0; i < k; ++i)
            if (mask&(1 << i))
                for (j = 0; j < k; ++j)
                    if (i != j && (mask&(1 << j)))
                        d[i][mask] = MINIM(d[i][mask], d[j][mask - (1 << i)] + dis[v[j]][v[i]]);
    mini = INF;
    for (i = 0; i <= k; ++i)
        mini = MINIM(mini, d[i][((1 << k) - 1)] + dis[v[i]][n]);
    g << mini;
    return 0;
}