Cod sursa(job #3258900)

Utilizator CaldareaCiprianCaldarea Ciprian CaldareaCiprian Data 24 noiembrie 2024 10:59:07
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
using VI = vector<int>;
using VVI = vector<VI>;
using VPI = vector<pair<int, int>>;
using PI = pair<int, int>;
using VVPI = vector<VPI>;
using VB = vector<bool>;
VVPI G;
const int INF = 0x3f3f3f;
int n, k, e;
void Dijkstra(int r, VI& d)
{
    VB mark(n + 1);
    priority_queue<PI, VPI, greater<PI>> Q;
    Q.emplace(0, r);
    d[r] = 0;
    int u;
    while (!Q.empty())
    {
        u = Q.top().second;
        Q.pop();

        if (mark[u])
            continue;

        mark[u] = true;

        for (auto i : G[u])
        {
            if (d[i.first] > d[u] + i.second)
            {
                d[i.first] = d[u] + i.second;
                Q.emplace(d[i.first], i.first);
            }
        }
    }
}


int main()
{

    fin >> n >> e;
    fin >> k;
    VI prieteni(k + 1);
    G = VVPI(n + 1);
    for (int i = 1;  i <= k; ++i)
    {
        fin >> prieteni[i];
    }
    int fir, sec, val;
    for (int i = 1; i <= e; ++i)
    {
        fin >> fir >> sec >> val;
        G[fir].emplace_back(sec, val);
        G[sec].emplace_back(fir, val);
    }

    VVI dist(k + 1, VI(n + 1, INF));

    for (int i = 1; i <= k; ++i)
    {
        Dijkstra(prieteni[i], dist[i]);
    }



    VVI dp = VVI((1 << k) + 3, VI(k + 1, INF));

    for (int i = 0; i < k; ++i)
    {
        dp[1 << i][i + 1] = dist[i + 1][1];
    }


    for (int mask = 1; mask < (1 << (k)); ++mask)
    {
        for (int i = 1; i <= k; ++i)
        {
            if (((1 << (i - 1)) & mask) == 0)
            {
                for (int j = 1; j <= k; ++j)
                    if (((1 << (j - 1)) & mask) != 0)
                    {
                        dp[mask | (1 << (i - 1))][i] = min(dp[mask][j] + dist[i][prieteni[j]], dp[mask | (1 << (i - 1))][i]);
                    }
            }
        }
    }
    int mi = INF;
    for (int i = 1; i <= k; ++i)
    {
        mi = min(mi, dp[(1 << k) - 1][i] + dist[i][n]);
    }

    if (k == 0)
        {
            VI distan(n + 10, INF);
            Dijkstra(1, distan);
            fout << distan[n] << '\n';
        }
    else
        fout << mi;
}