Cod sursa(job #2937093)

Utilizator AswVwsACamburu Luca AswVwsA Data 9 noiembrie 2022 21:35:49
Problema Ubuntzei Scor 55
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <fstream>
//#include <iostream>
#include <climits>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

//dp[mask][i] = lungimea minima a unui traseu care trece prin
//localitatile date de mask si care se termina in localitatea
//i
//dp[2^i][i] = distmin(0, i)
//dp[masca][j] = min(dp[masca - 2^j][oricare din bitii din masca - 2^j]
//                  + distmin(localitatea data de bit, j))

//ans = min(dp[2^k - 1][i] + distmin(i, n - 1)), cu 0 <= i <= n - 1
//lmao, m-am tampit, am crezut ca in enunt scrie max(15, n - 2), nu min

const int NMAX = 2003;
const int KMAX = 16;
vector <pair <int, int> > g[NMAX];

struct ob
{
    int masca;
    int dist;
    int last;
};

bool operator <(ob a, ob b)
{
    return a.dist > b.dist;
}
priority_queue <ob> q;
int dp[(1 << KMAX)][NMAX];
int c[KMAX];

int special[NMAX];
int main()
{
    ifstream cin("ubuntzei.in");
    ofstream cout("ubuntzei.out");
    int n, m, i, j;
    cin >> n >> m;
    int k;
    cin >> k;
    for (i = 1; i <= k; i++)
    {
        cin >> c[i];
        special[c[i]] = i;
    }
    for (i = 1; i <= m; i++)
    {
        int a, b, x;
        cin >> a >> b >> x;
        g[a].push_back({b, x});
        g[b].push_back({a, x});
    }
    for (i = 0; i < (1 << k); i++)
        for (j = 1; j <= n; j++)
            dp[i][j] = INT_MAX / 2;
    q.push({0, 0, 1});
    while (!q.empty())
    {
        ob f = q.top();
       // cout << f.masca << " " << f.dist << " " << f.last << "\n";
        q.pop();
        if (dp[f.masca][f.last] < f.dist)
        {
            continue;
        }
        dp[f.masca][f.last] = f.dist;
        for (pair <int, int> u : g[f.last])
        {
            int mask = f.masca;
            if (special[u.first])
                mask |= ((1 << (special[u.first] - 1)));
            if (dp[mask][u.first] > dp[f.masca][f.last] + u.second)
            {
                dp[mask][u.first] = dp[f.masca][f.last] + u.second;
                q.push({mask, dp[mask][u.first], u.first});
            }
        }
    }
    cout << dp[(1 << k) - 1][n];
}