Cod sursa(job #2937121)

Utilizator AswVwsACamburu Luca AswVwsA Data 9 noiembrie 2022 22:42:58
Problema Ubuntzei Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.28 kb
//fuck off, ass problem
#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

//am bagat printre localitati si pe 1 si n, ca sa fie mai simplu
//chestia misto e ca toate celelalte localitati pot fi sterse,
//facand doar drumurile intre cele speciale si restul, ca mai apoi
//sa stiu distmin(localitate i, localitate j)
//(pana la urma, i in dp poate fi doar o localitate de acolo,
//nu o localitate care nu e "speciala")

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

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

int dp[(1 << KMAX)][KMAX];
bool special[NMAX];

void dijkstra(int nod)
{
    q.push({c[nod], 0});
    while (!q.empty())
    {
        ob f = q.top();
        q.pop();
        if (d[nod][f.last] < f.dist)
        {
            continue;
        }
        d[nod][f.last] = f.dist;
        for (pair <int, int> u : g[f.last])
            if (d[nod][u.first] > d[nod][f.last] + u.second)
            {
                d[nod][u.first] = d[nod][f.last] + u.second;
                q.push({u.first, d[nod][u.first]});
            }
    }
}

pair <int, int> masca[KMAX];
int main()
{
    ifstream cin("ubuntzei.in");
    ofstream cout("ubuntzei.out");
    int n, m, i, j;
    cin >> n >> m;
    int k;
    cin >> k;
    for (i = 0; i < k; i++)
    {
        int x;
        cin >> x;
        x--;
        special[x] = 1;
    }
    int dim = 0;
    special[0] = special[n - 1] = 1;
    for (i = 0; i < n; i++)
        if (special[i])
            c[dim++] = i;
    for (i = 1; i <= m; i++)
    {
        int a, b, x;
        cin >> a >> b >> x;
        a--;
        b--;
        g[a].push_back({b, x});
        g[b].push_back({a, x});
    }
    for (i = 0; i < dim; i++)
    {
        for (j = 0; j < n; j++)
            d[i][j] = INT_MAX / 2;
        dijkstra(i);
    }/*
    for (i = 0; i < dim; i++, cout << "\n")
        for (j = 0; j < n; j++)
            cout << d[i][j] << " ";
    cout << "\n";*/
    int lim = (1 << dim);
    for (i = 0; i < lim; i++)
        for (j = 0; j < dim; j++)
            dp[i][j] = INT_MAX / 2;
    dp[1][0] = 0;
    for (i = 1; i < lim; i++)
    {
        vector <int> aux;
        masca[i].second = i;
        for (j = 0; (1 << j) <= i; j++)
            if ((1 << j) & i)
            {
                masca[i].first++;
            }
    }
    sort(masca + 1, masca + lim);
    /*for (i = 1; i < lim; i++)
        cout << masca[i].first << " " << masca[i].second << "\n";
    return 0;*/
    for (i = 1; i < lim; i++)
    {
        //cout << masca[i].first << " " << masca[i].second << ":";
        vector <int> aux;
        for (j = 0; (1 << j) <= masca[i].second; j++)
            if ((1 << j) & masca[i].second)
            {
                aux.push_back(j);
            }
        for (j = 0; j < aux.size(); j++)
        {
            //cout << aux[j] << " ";
            //dp[i][j] = min(dp[i - (1 << j)][
            for (int ind = 0; ind < dim; ind++)
                if (ind != aux[j])
                {
                   // cout << dp[masca[i].second - (1 << aux[j])][ind] << " " << d[ind][c[aux[j]]] << "\n";
                  //  cout << masca[i].second << " " << aux[j] << " " << masca[i].second - (1 << aux[j]) << " " << ind << " " << dp[masca[i].second - (1 << aux[j])][ind] << "\n";
                    dp[masca[i].second][aux[j]] = min(dp[masca[i].second][aux[j]],
                                                      dp[masca[i].second - (1 << aux[j])][ind] + d[ind][c[aux[j]]]);
                }
        }
       // cout << "\n";
    }
    //cout << d[1][4] << " ";
    cout << dp[(1 << dim) - 1][dim - 1];
}