Cod sursa(job #2660868)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 20 octombrie 2020 18:54:42
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <fstream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

const int NMAX = 2000;
const int KMAX = 15;

int n, m, k;

vector<pair<int ,int>> graf[1 + NMAX];
vector<int> special;

int dist[1 + KMAX][1 + NMAX];

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

int dp[1 + KMAX][1 << KMAX];

void dijkstra(int idx, int sursa)
{
    dist[idx][sursa] = 0;
    pq.push(make_pair(0, sursa));

    while (!pq.empty())
    {
        int nod = pq.top().second;
        int cost = pq.top().first;
        pq.pop();

        if (cost > dist[idx][nod]) continue;

        for (int i = 0; i < graf[nod].size(); i++)
        {
            int vecin = graf[nod][i].second;
            int drum = graf[nod][i].first;

            if (cost + drum < dist[idx][vecin])
            {
                dist[idx][vecin] = cost + drum;
                pq.push(make_pair(cost + drum, vecin));
            }
        }
    }
}

int calcDp(int nod, int masca)
{
    if (dp[nod][masca] != 0)
      return dp[nod][masca];

    if (masca == (1 << nod))
    {
      dp[nod][masca] = dist[nod][1];
      return dp[nod][masca];
    }

    dp[nod][masca] = INT_MAX;

    int anterior = masca - (1 << nod);
    for (int i = 0; i < k; i++)
    {
        if (anterior & (1 << i))
            dp[nod][masca] = min(dp[nod][masca], calcDp(i, anterior));
    }

    return dp[nod][masca];
}


int main()
{
    ifstream in("ubuntzei.in");
    ofstream out("ubuntzei.out");

    in >> n >> m >> k;

    for (int i = 1; i <= k; i++)
    {
        int x;
        in >> x;
        special.push_back(x);
    }

    for (int i = 1; i <= m; i++)
    {
        int a, b, c;
        in >> a >> b >> c;
        graf[a].push_back(make_pair(c, b));
        graf[b].push_back(make_pair(c, a));
    }

    for (int i = 0; i < special.size(); i++)
    {
        for (int j = 1; j <= n; j++)
        {
            dist[i][j] = INT_MAX;
        }
    }

    for (int i = 0; i < special.size(); i++)
    {
        dijkstra(i, special[i]);
    }

    int sol = INT_MAX;
    for (int i = 0; i < k; i++)
    {
        sol = min(sol, calcDp(i, (1 << k) - 1) + dist[i][n]);
    }

    if (k == 0)
    {
      for (int j = 1; j <= n; j++)
      {
          dist[1][j] = INT_MAX;
      }
      dijkstra(1, 1);

      sol = dist[1][n];
    }

    out << sol << '\n';

    return 0;
}