Cod sursa(job #3003347)

Utilizator RobertAcAcatrinei Robert-Marian RobertAc Data 15 martie 2023 17:55:26
Problema Ubuntzei Scor 65
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <bits/stdc++.h>
// #define in cin
// #define out cout
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
using namespace std;

ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int kmax = 19;
const int nmax = 2005;

int n, m;
int dist[kmax][kmax];
int distt[nmax][nmax];
bool toFind[nmax];
bool viz[nmax];
bool viz2[1 << (kmax)][kmax]; // daca am vizitat nodul

vector<int> ks = {1};

struct node
{
    int ind, val;
    node(int ind, int val) : ind(ind), val(val) {}

    bool operator<(const node &other) const
    {
        return val > other.val;
    }
};

struct muchie
{
    int nxt, val;
    muchie(int nxt, int val) : nxt(nxt), val(val) {}
};

vector<muchie> adj[nmax];

void dijkstra(int nod)
{
    memset(viz, 0, sizeof viz);
    priority_queue<node> pq;
    pq.push(node(nod, 0));

    while (!pq.empty())
    {
        auto nodd = pq.top();
        pq.pop();

        int ind = nodd.ind;
        int val = nodd.val;

        if (viz[ind])
            continue;
        viz[ind] = 1;

        if (toFind[ind])
        {
            distt[nod][ind] = val;
        }

        for (auto i : adj[ind])
        {
            pq.push(node(i.nxt, val + i.val));
        }
    }
}

struct node2
{
    int mask, ind, val;
    node2(int ind, int val, int mask) : ind(ind), val(val), mask(mask) {}
    bool operator<(const node2 &other) const
    {
        return val > other.val;
    }
};
int k;

int sol = INT_MAX;

void dijk2()
{
    int maskToFind = (1 << (k + 1)) - 1;
    priority_queue<node2> pq;
    pq.push(node2(0, 0, 1));

    while (!pq.empty())
    {
        auto nodd = pq.top();

        pq.pop();

        int mask = nodd.mask;
        int ind = nodd.ind;
        int val = nodd.val;

        bitset<20> b(mask);

        // out << ind << ' ' << val << ' ' << b << '\n';

        if (viz2[mask][ind])
            continue;
        viz2[mask][ind] = 1;

        if (mask == maskToFind)
        {
            sol = min(sol, val + dist[ind][k]);
        }

        for (int i = 0; i <= k; i++)
        {
            if (mask | (1 << i) != mask)
            {
                pq.push(node2(i, val + dist[ind][i], mask | ((1 << i))));
            }
        }
    }
}

int main()
{
    in >> n >> m;
    in >> k;

    for (int i = 0; i < k; i++)
    {
        int a;
        in >> a;
        ks.push_back(a);
    }
    ks.push_back(n);

    for (auto i : ks)
        toFind[i] = 1;

    for (int i = 0; i < m; i++)
    {
        int a, b, c;
        in >> a >> b >> c;
        adj[a].push_back(muchie(b, c));
        adj[b].push_back(muchie(a, c));
    }

    for (auto i : ks)
        dijkstra(i);

    for (int i = 0; i < ks.size(); i++)
    {
        for (int j = 0; j < ks.size(); j++)
        {
            dist[i][j] = distt[ks[i]][ks[j]];
            // out<<i<<' '<<j<<' '<<dist[i][j]<<'\n';
        }
        // out<<'\n';
    }

    k++;
    dijk2();
    out << sol;
}