Cod sursa(job #3278999)

Utilizator Mihai_999Diaconeasa Mihai Mihai_999 Data 21 februarie 2025 17:30:38
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#define nl '\n'

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int NMAX = 2e3+5, KMAX = 17, INF = 1e9+5;

int n, m, k, translate[NMAX], ubuntz[KMAX+5], cost[KMAX][KMAX], dist[NMAX], dp[KMAX][(1<<KMAX)];

struct muchie
{
    int nod, cost;
};
vector<muchie> adj[NMAX];
muchie crt;

bool operator <(const muchie& a, const muchie& b)
{
    if (a.cost == b.cost)
        return a.nod < b.nod;
    return a.cost < b.cost;
}

set<muchie> q;

int main()
{
    fin >> n >> m;
    fin >> k;
    for (int i = 1; i <= k; i++)
    {
        fin >> ubuntz[i];
        translate[ubuntz[i]] = i;
    }
    ubuntz[0] = 1;
    translate[1] = 0;
    ubuntz[k+1] = n;
    translate[n] = k+1;
    k+=2;
    for (int i = 1; i <= m; i++)
    {
        int u, v, w;
        fin >> u >> v >> w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }
    for (int start = 0; start < k; start++)
    {
        for (int i = 1; i <= n; i++)
           dist[i] = INF;
        dist[ubuntz[start]] = 0;
        q.insert({ubuntz[start], 0});
        while (!q.empty())
        {
            crt = *(q.begin());
            q.erase(q.begin());
            for (const muchie& mm : adj[crt.nod])
            {
                if (crt.cost+mm.cost < dist[mm.nod])
                {
                    if (dist[mm.nod] != INF)
                        q.erase({mm.nod, dist[mm.nod]});
                    dist[mm.nod] = crt.cost+mm.cost;
                    q.insert({mm.nod, dist[mm.nod]});
                }
            }
        }
        for (int i = 0; i < k; i++)
            cost[start][i] = dist[ubuntz[i]];
    }
    for (int i = 0; i < k; i++)
        for (int mask = 0; mask < (1<<k); mask++)
            dp[i][mask] = INF;
    dp[0][1] = 0;
    for (int mask = 2; mask < (1<<k); mask++)
    {
        if (!(mask&1))
            continue;
        for (int j = 0; j < k; j++)
        {
            if (mask&(1<<j))
            {
                for (int p = 0; p < k; p++)
                {
                    if (p == j)
                        continue;
                    if (mask&(1<<p))
                        dp[j][mask] = min(dp[j][mask], dp[p][mask^(1<<j)]+cost[p][j]);
                }
            }
        }
    }
    fout << dp[k-1][(1<<k)-1];
    return 0;
}